package com.lyf.scm.plan.domain.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.ImmutableList;
import com.lyf.scm.common.constants.BigDataEsConstants;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.*;
import com.lyf.scm.common.model.ExcelExportDataDTO;
import com.lyf.scm.common.model.SalesPlanSelectDTO;
import com.lyf.scm.common.util.AdvancedSearchUtil;
import com.lyf.scm.common.util.ExcelExportUtil;
import com.lyf.scm.common.util.date.MyDateUtil;
import com.lyf.scm.common.util.style.GeneralCellWriteHandler;
import com.lyf.scm.plan.api.dto.*;
import com.lyf.scm.plan.api.dto.excel.SalesWriteDTO;
import com.lyf.scm.plan.domain.remote.basedata.dto.AreaDTO;
import com.lyf.scm.plan.domain.remote.basedata.dto.StoreDTO;
import com.lyf.scm.plan.domain.remote.basedata.facade.BaseDataFacade;
import com.lyf.scm.plan.domain.remote.category.dto.StorePackageSkuDTO;
import com.lyf.scm.plan.domain.remote.category.facade.CategoryFacade;
import com.lyf.scm.plan.domain.remote.item.dto.*;
import com.lyf.scm.plan.domain.remote.item.facade.ItemCoreFacade;
import com.lyf.scm.plan.domain.remote.nateWork.dto.SearchSourceToCQueryDTO;
import com.lyf.scm.plan.domain.remote.nateWork.facade.NateWorkFacade;
import com.lyf.scm.plan.domain.remote.transaction.facade.TransactionFacade;
import com.lyf.scm.plan.domain.repository.OperationLogRecordRepository;
import com.lyf.scm.plan.domain.repository.SalesPlanOtherEsRepository;
import com.lyf.scm.plan.domain.repository.SalesPlanOtherRespository;
import com.lyf.scm.plan.domain.repository.SalesPlanPermissionsRespository;
import com.lyf.scm.plan.domain.service.CommonService;
import com.lyf.scm.plan.domain.service.RedisCacheService;
import com.lyf.scm.plan.domain.service.SalesPlanOtherEsService;
import com.lyf.scm.plan.insfrastructure.db.dataobject.es.SalesPlanEsEntity;
import com.rome.arch.core.exception.RomeException;
import com.rome.arch.util.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.InternalTerms;
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.sum.InternalSum;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ScrolledPage;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * 其他销售计划-调ES的api
 *
 * @author Martin
 * @date 2020-10-23 21:04
 */
@Slf4j
@Service
public class SalesPlanOtherEsServiceImpl implements SalesPlanOtherEsService {

    private static final String SALES_PLAN_INDEX_NAME = "scm_sales_plan_index";
    private static final String GROUP_SKU_CODE = "skuCodeGroup";
    private static final String GROUP_AREA = "cityCodeGroup";
    private static final String GROUP_PLAN_TYPE = "planTypeGroup";
    private static final String GROUP_CHANNEL_CODE = "channelCodeGroup";
    private static final String GROUP_DATE = "dateGroup";
    /**
     * 价格map，key是sku
     */
    private Map<String, BigDecimal> avgPriceMap = new HashMap<>();
    @Resource
    private SalesPlanOtherRespository salesPlanOtherRespository;
    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;
    @Resource
    private CommonService commonService;

    @Resource
    private ItemCoreFacade itemCoreFacade;

    @Resource
    private BaseDataFacade baseDataFacade;

    @Resource
    private CategoryFacade categoryFacade;

    @Resource
    private TransactionFacade transactionFacade;

    @Resource
    private OperationLogRecordRepository operationLogRecordRepository;

    @Resource
    private SalesPlanPermissionsRespository salesPlanPermissionsRespository;

    @Resource
    private SalesPlanOtherEsRepository salesPlanOtherEsRepository;

    @Resource
    private RedisCacheService redisCacheService;

    @Resource
    private NateWorkFacade nateWorkFacade;

    /**
     * 按条件查询其他渠道计划（周）
     *
     * @param salesPlanOther
     * @return
     */
    /*@Override
    public PageInfo<SalesPlanOtherInfoDTO> listWeekBySelective(SalesPlanOtherDTO salesPlanOther) {
        //根据日期获取间隔日期集合,没有结束时间，默认14周
        List<Map<String, Date>> weekDates = MyDateUtil.getWeekDates(salesPlanOther.getStartTime(), CommonConstants.WEEK_SIZE);
        salesPlanOther.setWeekDateList(weekDates);
        salesPlanOther.setEndTime(MyDateUtil.getLastDate(null, weekDates));
        PageInfo<SalesPlanOtherInfoDTO> dtoPageInfo = new PageInfo<>();
        Long userId = salesPlanOther.getCreator();
        //获取当前用户角色权限
        List<SalesPlanPermissionsDTO> roleAreaList = getRoleAreaList(userId);
        //一个用户只有一个级别（1:渠道、渠道下级（1级导入，确认），2：全渠道（2级确认））
        Integer level = roleAreaList.get(0).getPermissionsLevel();
        List<String> channels = new ArrayList<>();
        roleAreaList.forEach(item -> {
            String channel = item.getPermissionsCode();
            channels.add(channel);
        });
        //高级搜索不选择渠道，查询用户对应渠道
        if (CollectionUtils.isEmpty(salesPlanOther.getChannelCodeList())) {
            salesPlanOther.setChannelCodeList(channels);
        }
        //根据高级搜索条件查询分页的信息
        PageInfo<Map<String, String>> listPageInfo = salesPlanOtherRespository.listWeekBySelective(salesPlanOther);
        List<SalesPlanOtherInfoDTO> salesPlan = groupTarget(listPageInfo.getList(), level);
        if (CollectionUtils.isEmpty(salesPlan)) {
            return dtoPageInfo;
        }
        //转换单位(数据库存的基础单位，不用转换)
        if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(salesPlanOther.getUnitType())) {
            List<String> skuCodeList = salesPlan.stream().map(SalesPlanOtherInfoDTO::getSkuCode).distinct().collect(Collectors.toList());
            //处理单位
            List<SkuUnitDTO> skuUnitList = itemCoreFacade.getConversionRatio(skuCodeList, salesPlanOther.getUnitType());
            this.calculationProBySelect(salesPlan, skuUnitList);
        }
        dtoPageInfo.setList(salesPlan);
        dtoPageInfo.setTotal(listPageInfo.getTotal());
        return dtoPageInfo;
    }*/
    private List<SalesPlanPermissionsDTO> getRoleAreaList(Long userId) {
        //获取当前用户角色权限
        List<SalesPlanPermissionsDTO> roleAreaList = salesPlanPermissionsRespository.listByUserId(userId);
        if (CollectionUtils.isEmpty(roleAreaList)) {
            throw new RomeException(ResponseMsg.FAIL_2004.getCode(), ResponseMsg.FAIL_2004.getMsg());
        }
        //渠道不为空为其他渠道计划用户
        roleAreaList = roleAreaList.stream().filter(item -> PermissionCodeEnum.CHANNEL.getCode().equals(item.getPermissionsType())).collect(Collectors.toList());
        if (roleAreaList.size() == 0) {
            throw new RomeException(ResponseMsg.FAIL_2004.getCode(), ResponseMsg.FAIL_2004.getMsg());
        }
        return roleAreaList;
    }

    /**
     * 查询全渠道其他渠道计划(范围)
     *
     * @param salesPlanOther
     * @return
     */
    /*@Override
    public List<SalesPlanOtherInfoDTO> listAllByCycles(SalesPlanOtherDTO salesPlanOther) {
        //如果开始时间为空
        if (ObjectUtil.isEmpty(salesPlanOther.getStartTime())) {
            salesPlanOther.setStartTime(DateUtil.beginOfWeek(new Date()));
        } else {
            salesPlanOther.setStartTime(DateUtil.beginOfWeek(salesPlanOther.getStartTime()));
        }
        //如果结束时间为空
        if (ObjectUtil.isEmpty(salesPlanOther.getEndTime())) {
            salesPlanOther.setEndTime(DateUtil.beginOfWeek(DateUtil.offsetWeek(new Date(), CommonConstants.WEEK_TARGET_SIZE)));
        } else {
            salesPlanOther.setEndTime(DateUtil.endOfWeek(salesPlanOther.getEndTime()));
        }
        List<Map<String, Date>> weekDates = MyDateUtil.getWeekDates(salesPlanOther.getStartTime(), CommonConstants.WEEK_SIZE);
        salesPlanOther.setWeekDateList(weekDates);
        Long userId = salesPlanOther.getCreator();
        //获取当前用户角色权限
        List<SalesPlanPermissionsDTO> roleAreaList = getRoleAreaList(userId);
        //一个用户只有一个级别（1:渠道、渠道下级（1级导入，确认），2：全渠道（2级确认））
        Integer level = roleAreaList.get(0).getPermissionsLevel();
        List<String> channels = new ArrayList<>();
        roleAreaList.forEach(item -> {
            String channel = item.getPermissionsCode();
            channels.add(channel);
        });
        if (CollectionUtils.isEmpty(salesPlanOther.getChannelCodeList())) {
            salesPlanOther.setChannelCodeList(channels);
        }
        List<SalesPlanOtherDTO> resultList = salesPlanOtherRespository.listAllByCycles(salesPlanOther);
        if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(salesPlanOther.getUnitType())) {
            //获取不重复的skuCode集合
            List<String> skuCodeList = resultList.stream().map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.toList());
            //获取单位换算比例
            List<SkuUnitDTO> skuUnitList = itemCoreFacade.getConversionRatio(skuCodeList, salesPlanOther.getUnitType());
            //根据获取的换算比例计算指标数量
            this.calculationPro(resultList, skuUnitList);
        }
        //设置分组依据的key值
        this.getGroupByKey(resultList, salesPlanOther);
        //将数据分组
        Map<String, List<SalesPlanOtherDTO>> paramMap = resultList.stream().collect(Collectors.groupingBy(SalesPlanOtherDTO::getCondition, Collectors.toList()));
        // 汇总分组后的数据
        List<SalesPlanOtherInfoDTO> salesPlanDirectlyList = this.getTargetList(paramMap, salesPlanOther, level);
        return salesPlanDirectlyList;
    }*/

    /**
     * 汇总分组后的数据
     *
     * @param paramMap       参数映射
     * @param salesPlanOther 其他渠道计划
     * @param level          级别
     * @return {@link List<SalesPlanOtherInfoDTO>}
     */
    /*private List<SalesPlanOtherInfoDTO> getTargetList(Map<String, List<SalesPlanOtherDTO>> paramMap, SalesPlanOtherDTO salesPlanOther, Integer level*//*, List<SalesPlanOtherTypeDTO> typeList, List<SalesPlanOtherTypeDTO> typeImpList*//*) {
        List<SalesPlanOtherInfoDTO> salesPlanOtherInfoList = new ArrayList<>();
        List<Map<String, Date>> weekDateList = salesPlanOther.getWeekDateList();
        //将分组后的数据汇总
        paramMap.keySet().forEach(key -> {
            //上次计划量
            List<BigDecimal> lastPlanQtys = new ArrayList<>();
            //上次确认量
            List<BigDecimal> lastConfirmedQtys = new ArrayList<>();
            //计划量
            List<BigDecimal> planQtys = new ArrayList<>();
            //确认量
            List<BigDecimal> confirmedQtys = new ArrayList<>();
            //下级确认量
            List<BigDecimal> subordinateConfirms = new ArrayList<>();
            //计划差异
            List<BigDecimal> planDifferences = new ArrayList<>();
            //计划比例
            List<BigDecimal> planProportions = new ArrayList<>();
            //渠道确认量
            List<BigDecimal> channelConfirmedQtys = new ArrayList<>();
            //全渠道确认量
            List<BigDecimal> allchannelConfirmedQtys = new ArrayList<>();
            //渠道上次确认量
            List<BigDecimal> channelLastConfirmedQtys = new ArrayList<>();
            //全渠道上次确认量
            List<BigDecimal> allchannelLastConfirmedQtys = new ArrayList<>();
            SalesPlanOtherInfoDTO salesPlanOtherInfo = new SalesPlanOtherInfoDTO();
            // 设置上次计划量
            weekDateList.forEach(date -> lastPlanQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getLastPlanQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
            salesPlanOtherInfo.setLastPlanQtyLabel(SalesPlanOtherEnum.LAST_PLAN_QTY.getDesc());
            salesPlanOtherInfo.setLastPlanQtys(lastPlanQtys);
            // 设置计划量(导入人)
            weekDateList.forEach(date -> planQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getPlanQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
            salesPlanOtherInfo.setPlanQtyLabel(SalesPlanOtherEnum.PLAN_QTY.getDesc());
            salesPlanOtherInfo.setPlanQtys(planQtys);
            if (level.equals(CommonConstants.OTHER_PLAN_LEVEL_TWO)) {
                //设置上次确认量(全渠道)
                weekDateList.forEach(date -> lastConfirmedQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getAllchannelLastConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
                //设置确认量(全渠道)
                weekDateList.forEach(date -> confirmedQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getAllchannelConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
                // 设置下级确认量(全渠道)
                weekDateList.forEach(date -> subordinateConfirms.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getChannelConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
                salesPlanOtherInfo.setSubordinateConfirmedQtyLabel(SalesPlanOtherEnum.SUBORDINATE_CONFIRMED_QTY.getDesc());
                salesPlanOtherInfo.setSubordinateConfirmedQtys(subordinateConfirms);
            } else {
                //设置上次确认量(渠道)
                weekDateList.forEach(date -> lastConfirmedQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getChannelLastConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
                //设置确认量(渠道)
                weekDateList.forEach(date -> confirmedQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getChannelConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
                //设置上次确认量(导入)
                weekDateList.forEach(date -> lastConfirmedQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getLastConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
                //设置确认量(导入人)
                weekDateList.forEach(date -> confirmedQtys.add(paramMap.get(key).stream().filter(item -> item.getPlanStartDate().compareTo(date.get("startTime")) == 0 && item.getPlanEndDate().compareTo(date.get("endTime")) == 0).map(SalesPlanOtherDTO::getConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add)));
            }
            salesPlanOtherInfo.setLastConfirmedQtyLabel(SalesPlanOtherEnum.LAST_CONFIRMED_QTY.getDesc());
            salesPlanOtherInfo.setLastConfirmedQtys(lastConfirmedQtys);
            salesPlanOtherInfo.setConfirmedQtyLabel(SalesPlanOtherEnum.CONFIRMED_QTY.getDesc());
            salesPlanOtherInfo.setConfirmedQtys(confirmedQtys);
            salesPlanOtherInfo.setPlanDifferenceLabel(SalesPlanOtherEnum.PLAN_CONFIRMED_DIFFERIN.getDesc());
            salesPlanOtherInfo.setPlanProportionLabel(SalesPlanOtherEnum.PLAN_CONFIRMED_PROPORTION.getDesc());
            // 计划与确认差值:确认量（渠道）-计划量（渠道）
            for (int i = 0; i < weekDateList.size(); i++) {
                planDifferences.add(confirmedQtys.get(i).subtract(planQtys.get(i)).
                        compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : confirmedQtys.get(i).subtract(planQtys.get(i)));
            }
            // 计划与确认比例:(（确认量（渠道）- 计划量（渠道））/确认量（渠道）
            for (int i = 0; i < weekDateList.size(); i++) {
                planProportions.add(confirmedQtys.get(i).compareTo(BigDecimal.ZERO) == 0
                        || confirmedQtys.get(i).subtract(planQtys.get(i)).compareTo(BigDecimal.ZERO) == 0 ?
                        BigDecimal.ZERO : (confirmedQtys.get(i).subtract(planQtys.get(i))).divide(confirmedQtys.get(i), 7, BigDecimal.ROUND_HALF_UP));
            }
            salesPlanOtherInfo.setPlanDifferences(planDifferences);
            salesPlanOtherInfo.setPlanProportions(planProportions);
            salesPlanOtherInfo.setLevel(level);
            salesPlanOtherInfo.setType(paramMap.get(key).get(0).getType());
            //获取渠道、区域、商品信息
            this.getInfoData(paramMap.get(key), salesPlanOtherInfo, salesPlanOther.getSkuCodeList());
            salesPlanOtherInfoList.add(salesPlanOtherInfo);
        });
        return salesPlanOtherInfoList;
    }*/

    /**
     * 获取渠道、区域、商品信息
     *
     * @param salesPlanOthers
     * @param salesPlanOtherInfo
     * @param skuCodeList
     * @return
     */
    /*private SalesPlanOtherInfoDTO getInfoData(List<SalesPlanOtherDTO> salesPlanOthers, SalesPlanOtherInfoDTO salesPlanOtherInfo, List<String> skuCodeList) {
        // 区域信息
        salesPlanOtherInfo.setArea(
                salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getProvinceName())).map(SalesPlanOtherDTO::getProvinceName).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getCityName())).map(e -> "/" + e.getCityName()).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getCountyName())).map(e -> "/" + e.getCountyName()).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getStoreName())).map(e -> "/" + e.getStoreName()).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getStoreName())).map(e -> "/" + e.getStoreCode()).distinct().collect(Collectors.joining()));


        // 渠道信息
        salesPlanOtherInfo.setChannel(
                salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getChannelName())).map(SalesPlanOtherDTO::getChannelName).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSubChannelName())).map(e -> "/" + e.getSubChannelName()).distinct().collect(Collectors.joining()));
        // 品类信息
        salesPlanOtherInfo.setCategory(
                salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getPriCategoryName())).map(SalesPlanOtherDTO::getPriCategoryName).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSecCategoryName())).map(e -> "/" + e.getSecCategoryName()).distinct().collect(Collectors.joining()) +
                        salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getTerCategoryName())).map(e -> "/" + e.getTerCategoryName()).distinct().collect(Collectors.joining()));
        //sku信息
        if (CollectionUtils.isNotEmpty(skuCodeList)) {
            salesPlanOtherInfo.setSkuName(salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSkuCode())).map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.joining()) +
                    salesPlanOthers.stream().filter(item -> ObjectUtil.isNotNull(item.getSkuName())).map(e -> "/" + e.getSkuName()).distinct().collect(Collectors.joining()));
        }
        //一级渠道
        salesPlanOtherInfo.setChannelCode(salesPlanOthers.get(0).getChannelCode());
        salesPlanOtherInfo.setSubChannelCode(salesPlanOthers.get(0).getSubChannelCode());
        salesPlanOtherInfo.setPriCategoryCode(salesPlanOthers.get(0).getPriCategoryCode());
        salesPlanOtherInfo.setSecCategoryCode(salesPlanOthers.get(0).getSecCategoryCode());
        salesPlanOtherInfo.setTerCategoryCode(salesPlanOthers.get(0).getSecCategoryCode());
        salesPlanOtherInfo.setStoreCode(salesPlanOthers.get(0).getStoreCode());
        salesPlanOtherInfo.setProvinceCode(salesPlanOthers.get(0).getProvinceCode());
        salesPlanOtherInfo.setCityCode(salesPlanOthers.get(0).getCityCode());
        salesPlanOtherInfo.setCountyCode(salesPlanOthers.get(0).getCountyCode());
        salesPlanOtherInfo.setType(SalesOtherTypeEnum.getNameByType(salesPlanOthers.get(0).getType()));
        return salesPlanOtherInfo;
    }*/

    /**
     * @param salesPlanOtherPlans
     * @param salesPlanOther
     * @return
     */
    /*public List<SalesPlanOtherDTO> getGroupByKey(List<SalesPlanOtherDTO> salesPlanOtherPlans, SalesPlanOtherDTO salesPlanOther) {
        salesPlanOtherPlans.forEach(item -> {
            StringBuilder keyStr = new StringBuilder();
            keyStr.append(ObjectUtil.isNotNull(item.getChannelCode()) ? item.getChannelCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getSubChannelCode()) ? item.getSubChannelCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getPriCategoryCode()) ? item.getPriCategoryCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getSecCategoryCode()) ? item.getSecCategoryCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getTerCategoryCode()) ? item.getTerCategoryCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getProvinceCode()) ? item.getProvinceCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getCityCode()) ? item.getCityCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getCountyCode()) ? item.getCountyCode() : "");
            keyStr.append(ObjectUtil.isNotNull(item.getType()) ? item.getType() : "");
            if (CollectionUtils.isNotEmpty(salesPlanOther.getStoreCodeList())) {
                keyStr.append(ObjectUtil.isNotNull(item.getStoreCode()) ? item.getStoreCode() : "");
            }
            if (CollectionUtils.isNotEmpty(salesPlanOther.getSkuCodeList())) {
                keyStr.append(ObjectUtil.isNotNull(item.getSkuCode()) ? item.getSkuCode() : "");
            }
            item.setCondition(keyStr.toString());
        });
        return salesPlanOtherPlans;
    }*/

    /**
     * 获取当前用户其他渠道计划级别
     *
     * @param userId
     * @return
     */
    /*@Override
    public Integer getOtherPlanLevel(Long userId) {
        //获取当前用户角色权限
        List<SalesPlanPermissionsDTO> roleAreaList = getRoleAreaList(userId);
        //一个用户只有一个级别（1:渠道、渠道下级（1级导入，确认），2：全渠道（2级确认））
        Integer level = roleAreaList.get(0).getPermissionsLevel();
        return level;
    }*/

    /**
     * 查询条件有 渠道、计划类型、区域、品类、指标、商品编码
     * 1、指标对"解析返回结果"、"构造返回数据模型-聚合字段"有影响，可以判断解决
     * 2、其他条件对构造查询条件，
     */
    public Object pageQuery(SalesPlanOtherDTO salesPlanOtherDTO) {
        // 构造需要返回的数据模型
        TermsAggregationBuilder aggregation = getTermsAggregation();
        // 多条件查询
        SearchQuery groupQuery = getSearchQuery(aggregation, salesPlanOtherDTO);
        Aggregations aggregations = elasticsearchTemplate.query(groupQuery, SearchResponse::getAggregations);
        return this.dealResult(aggregations);
    }

    /**
     * 构造结果模型
     *
     * @return
     */
    private TermsAggregationBuilder getTermsAggregation() {
        // 计划开始日期
        TermsAggregationBuilder group0 = AggregationBuilders.terms(GROUP_DATE)
                .field("planStartDate").size(Integer.MAX_VALUE).shardSize(Integer.MAX_VALUE);
        // sku分组
        TermsAggregationBuilder group1 = AggregationBuilders.terms(GROUP_SKU_CODE)
                .field("skuCode.keyword").size(Integer.MAX_VALUE).shardSize(Integer.MAX_VALUE);
        group1.subAggregation(group0);
        // 区域分组，要根据搜索条件判断是哪一级区域 TODO
        TermsAggregationBuilder group2 = AggregationBuilders.terms(GROUP_AREA)
                .field("provinceCode.keyword").size(Integer.MAX_VALUE).shardSize(Integer.MAX_VALUE);
        group2.subAggregation(group1);
        // 计划类型分组
        TermsAggregationBuilder group3 = AggregationBuilders.terms(GROUP_PLAN_TYPE)
                .field("planType.keyword").size(Integer.MAX_VALUE).shardSize(Integer.MAX_VALUE);
        group3.subAggregation(group2);
        // 渠道分组
        TermsAggregationBuilder group4 = AggregationBuilders.terms(GROUP_CHANNEL_CODE)
                .field("channelCode.keyword").size(Integer.MAX_VALUE).shardSize(Integer.MAX_VALUE);
        group4.subAggregation(group3);

        // 求和，具体字段根据传入条件做筛选 TODO
        // 计划量
        group0.subAggregation(AggregationBuilders.sum("planQtySum").field("planQty"));
        // 确认量
//                .subAggregation(AggregationBuilders.sum("confirmQtySum").field("confirmQty.keyword"))
        // 上次确认量
//                .subAggregation(AggregationBuilders.sum("prePlanQtySum").field("prePlanQty.keyword"))
        //上次确认量
//                .subAggregation(AggregationBuilders.sum("preConfirmQtySum").field("preConfirmQty.keyword"));
        return group4;
    }

    private SearchQuery getSearchQuery(TermsAggregationBuilder aggregation, SalesPlanOtherDTO salesPlanOtherDTO) {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        // 渠道条件
        setMultiConditions(boolQueryBuilder, "channelCode", salesPlanOtherDTO.getChannelCodeList());
        // 计划类型
        setMultiConditions(boolQueryBuilder, "planType", salesPlanOtherDTO.getTypeList());

        setMultiConditions(boolQueryBuilder, "skuCode", salesPlanOtherDTO.getSkuCodeList());

        // 日期
        String startDate = salesPlanOtherDTO.getPlanDate();
        String endDate = MyDateUtil.getDateAfterWeek(startDate, 13);
        RangeQueryBuilder planStartDate = rangeQuery("planStartDate").gte(startDate).lte(endDate);
        boolQueryBuilder.must(planStartDate);
        boolQueryBuilder.mustNot(QueryBuilders.matchQuery("plan_type", "17"));
        return new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withIndices(SALES_PLAN_INDEX_NAME)
                .addAggregation(aggregation)
                .build();
    }

    /**
     * 导入批量新增
     *
     * @param dtos
     * @param type
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer importPlanType(List<SalesPlanOtherDTO> dtos, Integer type, Long id) {
        Long modifier = dtos.get(0).getModifier();
        String modifierName = dtos.get(0).getModifierName();
        // 开始时间
        long start = System.currentTimeMillis();
        try {
            //修改上次计划量、上次确认量数据
            updateLastDate(dtos, type);
            //查询数据库是否存在导入数据
            //处理重复数据（转换为）
            List<SalesPlanEsEntity> dateLists = dealData(dtos, null, null);
            List<SalesPlanEsEntity> updateList = new ArrayList<>();
            List<SalesPlanOtherDTO> insertList = new ArrayList<>();
            //获取所有不重复的商品code
            List<String> skuCodeList = dtos.stream().filter(item -> ObjectUtil.isNotNull(item.getSkuCode())).map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.toList());
            //处理单位(查出销售单位换算比例)
            List<SkuUnitDTO> skuUnitLista = new ArrayList<>();
            //统一销售单位
            skuUnitLista = itemCoreFacade.getConversionRatio(skuCodeList, SkuUnitTypeEnum.SALES_UNIT.getUnitType());
            //如果获取商品比例数量与导入商品数量不一致，提示转换失败
            if (skuCodeList.size() != skuUnitLista.size()) {
                List<String> skuUnits = skuUnitLista.stream().map(SkuUnitDTO::getSkuCode).collect(Collectors.toList());
                List<String> reduce = skuCodeList.stream().filter(item -> !skuUnits.contains(item)).collect(Collectors.toList());
                throw new RomeException("9999", "商品转换销售单位比例失败" + ",商品编码为：" + reduce);
            }
            this.calculationProBySale(dtos, skuUnitLista);
            //处理单位(查出基础单位换算比例)
            List<SkuUnitDTO> skuUnitList = itemCoreFacade.getConversionRatio(skuCodeList, SkuUnitTypeEnum.BASIS_UNIT.getUnitType());
            this.calculationPro(dtos, skuUnitList);
            Integer result = 0;
            //导入销售计划
            if (type == 1) {
                //不为空说明导入有重复数据
                if (CollectionUtils.isNotEmpty((dateLists))) {
                    for (SalesPlanOtherDTO dtoa : dtos) {
                        //判断
                        List<SalesPlanEsEntity> repeats = dateLists.stream().filter(item ->
                                item.getChannel().equals(dtoa.getChannelCode()) &&
                                        item.getPlan_type().equals(dtoa.getType()) &&
                                        item.getProvince_code().equals(dtoa.getProvinceCode()) &&
                                        (ObjectUtil.isNull(dtoa.getCityCode()) ? true : (ObjectUtil.isNull(item.getCity_code()) ? false : item.getCity_code().equals(dtoa.getCityCode()))) &&
                                        (ObjectUtil.isNull(dtoa.getStoreCode()) ? true : (ObjectUtil.isNull(item.getNode_id()) ? false : item.getNode_id().equals(dtoa.getStoreCode()))) &&
                                        item.getSku_key().equals(dtoa.getSkuCode()) &&
                                        DateUtil.parseDate(item.getStart_date()).compareTo(dtoa.getPlanStartDate()) == 0)
                                .collect(Collectors.toList());
                        //说明同一个省份下有多条记录
                        if (repeats.size() > 1) {
                            //如果只有省
                            if (ObjectUtil.isNull(dtoa.getCityCode()) && ObjectUtil.isNull(dtoa.getStoreCode())) {
                                //过滤去掉城市和门店为空的省份数据
                                repeats = repeats.stream().filter(repeat -> ObjectUtil.isNull(repeat.getCity_code())
                                        && ObjectUtil.isNull(repeat.getNode_id())).collect(Collectors.toList());
                            }
                            //如果有省和城市
                            else if (ObjectUtil.isNotNull(dtoa.getCityCode()) && ObjectUtil.isNull(dtoa.getStoreCode())) {
                                //过滤去掉门店为空的数据
                                repeats = repeats.stream().filter(repeat -> ObjectUtil.isNull(repeat.getNode_id())).collect(Collectors.toList());
                            }
                        }
                        //修改
                        if (repeats.size() == 1) {
                            SalesPlanEsEntity dto = repeats.get(0);
                            //重复的数据,数据量覆盖
                            dto.setConfirm_l3(dtoa.getPlanQty());
                            dto.setPredict_sales(dtoa.getPlanQty());
                            //dto.setImport_date(DateUtil.formatDate(new Date()));
                            dto.setImport_date(DateUtil.formatDate(dtos.get(0).getPlanImportDate()));
                            updateList.add(dto);
                        } else {
                            insertList.add(dtoa);
                        }
                    }
                    if (updateList.size() > 0) {
                        asyncUpdateOtherEsData1(updateList);
                    }
                    dtos = insertList;
                    if (insertList.size() > 0) {
                        asyncInsertOtherEsData(dtos);
                    }
                } else {
                    asyncInsertOtherEsData(dtos);
                }
            } else if (type == 2) {
                //新开店
                //不为空说明导入有重复数据
                if (CollectionUtils.isNotEmpty((dateLists))) {
                    for (SalesPlanOtherDTO dtoa : dtos) {
                        //判断是否重复
                        List<SalesPlanEsEntity> repeats = dateLists.stream().filter(item ->
                                item.getPlan_type().equals(dtoa.getType())
                                        && item.getChannel().equals(dtoa.getChannelCode())
                                        && item.getProvince_code().equals(dtoa.getProvinceCode())
                                        && (ObjectUtil.isNull(dtoa.getCityCode()) ? true : (ObjectUtil.isNull(item.getCity_code()) ? false : item.getCity_code().equals(dtoa.getCityCode())))
                                        && item.getSku_key().equals(dtoa.getSkuCode())
                                        && DateUtil.parseDate(item.getStart_date()).compareTo(dtoa.getPlanStartDate()) == 0)
                                .collect(Collectors.toList());
                        //说明同一个省份下有多条记录
                        if (repeats.size() > 1) {
                            //如果只有省
                            if (ObjectUtil.isNull(dtoa.getCityCode())) {
                                //过滤去掉城市和门店为空的省份数据
                                repeats = repeats.stream().filter(repeat -> ObjectUtil.isNull(repeat.getCity_code())
                                ).collect(Collectors.toList());
                            }
                        }
                        //修改
                        if (repeats.size() == 1) {
                            SalesPlanEsEntity dto = repeats.get(0);
                            //dto.setImport_date(DateUtil.formatDate(new Date()));
                            dto.setImport_date(DateUtil.formatDate(dtos.get(0).getPlanImportDate()));
                            dto.setPredict_sales(dtoa.getPlanQty());
                            dto.setConfirm_l3(dtoa.getChannelConfirmedQty());
                            dto.setConfirm_l4(dtoa.getAllchannelConfirmedQty());
                            updateList.add(dto);
                        } else {
                            //新增
                            insertList.add(dtoa);
                        }
                    }
                    if (updateList.size() > 0) {
                        asyncUpdateOtherEsData1(updateList);
                    }
                    dtos = insertList;
                    if (insertList.size() > 0) {
                        asyncInsertOtherEsData(dtos);
                    }
                } else {
                    asyncInsertOtherEsData(dtos);
                }

            } else {
                //新品铺货
                //不为空说明导入有重复数据
                if (CollectionUtils.isNotEmpty((dateLists))) {
                    for (SalesPlanOtherDTO dtoa : dtos) {
                        //直营、加盟可能会有门店
                        List<SalesPlanEsEntity> repeats = dateLists.stream().filter(item ->
                                item.getPlan_type().equals(dtoa.getType())
                                        && item.getChannel().equals(dtoa.getChannelCode())
                                        && item.getSku_key().equals(dtoa.getSkuCode())
                                        && DateUtil.parseDate(item.getStart_date()).compareTo(dtoa.getPlanStartDate()) == 0
                                        && item.getProvince_code().equals(dtoa.getProvinceCode())
                                        && (ObjectUtil.isNull(dtoa.getCityCode()) ? true : (ObjectUtil.isNull(item.getCity_code()) ? false : item.getCity_code().equals(dtoa.getCityCode())))
                                        && (ObjectUtil.isNull(dtoa.getStoreCode()) ? true : (ObjectUtil.isNull(item.getNode_id()) ? false : item.getNode_id().equals(dtoa.getStoreCode()))))
                                .collect(Collectors.toList());
                        //说明同一个省份下有多条记录
                        if (repeats.size() > 1) {
                            //如果只有省
                            if (ObjectUtil.isNull(dtoa.getCityCode()) && ObjectUtil.isNull(dtoa.getStoreCode())) {
                                //过滤去掉城市和门店为空的省份数据
                                repeats = repeats.stream().filter(repeat -> ObjectUtil.isNull(repeat.getCity_code())
                                        && ObjectUtil.isNull(repeat.getNode_id())).collect(Collectors.toList());
                            }
                            //如果有省和城市
                            else if (ObjectUtil.isNotNull(dtoa.getCityCode()) && ObjectUtil.isNull(dtoa.getStoreCode())) {
                                //过滤去掉门店为空的数据
                                repeats = repeats.stream().filter(repeat -> ObjectUtil.isNull(repeat.getNode_id())).collect(Collectors.toList());
                            }
                        }
                        //修改
                        if (repeats.size() == 1) {
                            SalesPlanEsEntity dto = repeats.get(0);
                            //dto.setImport_date(DateUtil.formatDate(new Date()));
                            dto.setImport_date(DateUtil.formatDate(dtos.get(0).getPlanImportDate()));
                            dto.setPredict_sales(dtoa.getPlanQty());
                            dto.setConfirm_l3(dtoa.getChannelConfirmedQty());
                            dto.setConfirm_l4(dtoa.getAllchannelConfirmedQty());
                            updateList.add(dto);
                        } else {
                            //新增
                            insertList.add(dtoa);
                        }
                    }
                    if (updateList.size() > 0) {
                        asyncUpdateOtherEsData1(updateList);
                    }
                    dtos = insertList;
                    if (insertList.size() > 0) {
                        asyncInsertOtherEsData(dtos);
                    }
                } else {
                    asyncInsertOtherEsData(dtos);
                }
            }
            OperationLogRecordDTO operationDto = new OperationLogRecordDTO();
            operationDto.setId(id);
            operationDto.setOpTime((int) (System.currentTimeMillis() - start) + "ms");
            operationDto.setOpEndTime(new Date());
            operationDto.setModifier(modifier);
            operationDto.setModifierName(modifierName);
            operationDto.setFailReason("导入成功，请刷新页面查看");
            operationDto.setOpStatus(OperationStatusEnum.SUCCESS.getType());
            operationLogRecordRepository.updateOperationLog(operationDto);
        } catch (Exception ex){
            OperationLogRecordDTO operationDtoa = new OperationLogRecordDTO();
            log.error("导入其他渠道计划失败", ex);
            operationDtoa.setId(id);
            operationDtoa.setFailReason("导入失败");
            operationDtoa.setOpTime((int) (System.currentTimeMillis() - start) + "ms");
            operationDtoa.setOpEndTime(new Date());
            operationDtoa.setModifier(modifier);
            operationDtoa.setModifierName(modifierName);
            operationDtoa.setOpStatus(OperationStatusEnum.FAIL.getType());
            operationLogRecordRepository.updateOperationLog(operationDtoa);
        }
        return null;
    }

    /**
     * 从营销中心获取数据新增到其他渠道计划表
     *
     * @param dtoList
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addPlanOtherData(List<SalesPlanOtherSimpleDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            throw new RomeException(ResponseMsg.PARAM_ERROR_2019.getCode(), ResponseMsg.PARAM_ERROR_2019.getMsg());
        }
        //单次导入不能超过10000行
        if (dtoList.size() > CommonConstants.PLAN_OTHER_IMPORT_MAX) {
            throw new RomeException(ResponseMsg.FAIL_2003.getCode(), ResponseMsg.FAIL_2003.getMsg());
        }
        dtoList.forEach(item -> {
            //活动编码必填
            if (ObjectUtil.isNull(item.getSalesPlanActivityNo())) {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2017.getCode(), ResponseMsg.PARAM_ERROR_2017.getMsg());
            }
            //渠道code必填
            if (ObjectUtil.isNull(item.getChannelCode())) {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2014.getCode(), ResponseMsg.PARAM_ERROR_2014.getMsg());
            }
            //省份不能为空
            if (ObjectUtil.isNull(item.getProvinceName())) {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2008.getCode(), ResponseMsg.PARAM_ERROR_2008.getMsg());
            }
            //商品编码必填
            if (ObjectUtil.isEmpty(item.getSkuCode())) {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2012.getCode(), ResponseMsg.PARAM_ERROR_2012.getMsg());
            }
            //商品数量或计划周期不能为空
            if (CollectionUtil.isNotEmpty(item.getList())) {
                if (ObjectUtil.isNull(item.getList().get(0).getConfirmedQty())) {
                    throw new RomeException(ResponseMsg.PARAM_ERROR_2013.getCode(), ResponseMsg.PARAM_ERROR_2013.getMsg());
                }
                if (ObjectUtil.isNull(item.getList().get(0).getPlanWeek())) {
                    throw new RomeException(ResponseMsg.PARAM_ERROR_2010.getCode(), ResponseMsg.PARAM_ERROR_2010.getMsg());
                }
            } else {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2011.getCode(), ResponseMsg.PARAM_ERROR_2010.getMsg());
            }
            //商品类型编码必填
            if (ObjectUtil.isNull(item.getSkuTypeCode())) {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2016.getCode(), ResponseMsg.PARAM_ERROR_2016.getMsg());
            }
            //单位不能为空
            if (ObjectUtil.isNull(item.getUnit())) {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2026.getCode(), ResponseMsg.PARAM_ERROR_2026.getMsg());
            }
        });
        //获取所有省份为江苏省的数据
        List<SalesPlanOtherSimpleDTO> simpleList = dtoList.stream().filter(item -> CommonConstants.PRO_NAME.contains(item.getProvinceName())).distinct().collect(Collectors.toList());
        simpleList.forEach(item -> {
            //省份为江苏省，城市不能为空
            if (ObjectUtil.isNull(item.getCityName())) {
                throw new RomeException(ResponseMsg.PARAM_ERROR_2009.getCode(), ResponseMsg.PARAM_ERROR_2009.getMsg());
            }
        });
        //需要拆分成门店的省份集合
        List<AreaDTO> provinceList = new ArrayList<>();
        //需要拆分成门店的城市集合
        List<AreaDTO> cityNameList = new ArrayList<>();
        //拆分门店对应的省名称集合
        List<AreaDTO> provinceNameListByCity = new ArrayList<>();
        //门店集合
        List<StoreDTO> storeList = new ArrayList<>();
        //门店对应的省份集合（不用拆分）
        List<AreaDTO> provinceListByStore = new ArrayList<>();
        //门店对应的城市集合（不用拆分）
        List<AreaDTO> cityListByStore = new ArrayList<>();
        //门店对应的县/区集合（不用拆分）
        List<AreaDTO> countyListByStore = new ArrayList<>();
        Boolean ifTrue;
        //获取所有不重复省份的名称
        List<String> provinceNams = dtoList.stream().map(SalesPlanOtherSimpleDTO::getProvinceName).distinct().collect(Collectors.toList());
        provinceList = baseDataFacade.listProvinceByList(provinceNams);
        ifTrue = provinceList.size() == provinceNams.size();
        if (!ifTrue) {
            List<String> proSt = provinceList.stream().map(AreaDTO::getName).collect(Collectors.toList());
            List<String> list = provinceNams.stream().filter(item -> !proSt.contains(item)).collect(Collectors.toList());
            throw new RomeException(ResponseMsg.FAIL_2043.getCode(), ResponseMsg.FAIL_2043.getMsg() + list);
        }
        //获取所有不重复城市的名称
        List<String> cityNames = dtoList.stream().filter(item -> ObjectUtil.isNotNull(item.getCityName())).map(SalesPlanOtherSimpleDTO::getCityName).distinct().collect(Collectors.toList());
        if (cityNames.size() > 0) {
            //根据城市名称获取城市信息
            cityNameList = baseDataFacade.listProvinceByList(cityNames);
            ifTrue = cityNameList.size() == cityNames.size();
            if (!ifTrue) {
                List<String> citySt = cityNameList.stream().map(AreaDTO::getName).collect(Collectors.toList());
                List<String> list = cityNames.stream().filter(item -> !citySt.contains(item)).collect(Collectors.toList());
                throw new RomeException(ResponseMsg.FAIL_2042.getCode(), ResponseMsg.FAIL_2042.getMsg() + list);
            }
            //获取省份编码
            List<String> provinces = cityNameList.stream().map(AreaDTO::getParentCode).collect(Collectors.toList());
            if (provinces.size() > 0) {
                provinceNameListByCity = baseDataFacade.listAreaInfoByCode(provinces);
            }
        }
        //获取所有不重复门店的编码
        List<String> storeCodes = dtoList.stream().filter(item -> ObjectUtil.isNotNull(item.getStoreCode())).map(SalesPlanOtherSimpleDTO::getStoreCode).distinct().collect(Collectors.toList());
        if (storeCodes.size() > 0) {
            //获取基础服务中心所有门店
            storeList = baseDataFacade.listStore(new StoreDTO()).getList();
            //筛选出表格中的门店
            storeList = storeList.stream().filter(f -> storeCodes.contains(f.getCode())).collect(Collectors.toList());
            List<String> stos = storeList.stream().map(StoreDTO::getCode).collect(Collectors.toList());
            List<String> noStoreList = storeCodes.stream().filter(item -> !stos.contains(item)).collect(Collectors.toList());
            if (noStoreList.size() > 0) {
                throw new RomeException(ResponseMsg.FAIL_2013.getCode(), ResponseMsg.FAIL_2013.getMsg() + ",错误门店code：" + noStoreList);
            }
            List<String> failDirectlyList = new ArrayList<>();
            List<String> failJoinList = new ArrayList<>();
            for (SalesPlanOtherSimpleDTO readDto : dtoList) {
                if (ObjectUtil.isNotNull(readDto.getStoreCode())) {
                    String channel = readDto.getChannelCode();
                    List<StoreDTO> storess = storeList.stream().filter(item -> item.getCode().equals(readDto.getStoreCode())).collect(Collectors.toList());
                    //如果为直营
                    if (channel.equals(ChannelTypeEnum.DIRECTLY_OPERATE.getCode())) {
                        if (!storess.get(0).getStoreProperties().equals(ShopTypeEnum.DIRECTLY_SHOP.getStoreProperties()) && !storess.get(0).getStoreProperties().equals(ShopTypeEnum.NON_BRANCH_SHOP.getStoreProperties()) && !storess.get(0).getStoreProperties().equals(ShopTypeEnum.POOL_SHOP.getStoreProperties())) {
                            failDirectlyList.add(readDto.getChannelCode() + "-" + readDto.getStoreCode());
                        }
                    } else {
                        if (!storess.get(0).getStoreProperties().equals(ShopTypeEnum.JOIN_SHOP.getStoreProperties()) && !storess.get(0).getStoreProperties().equals(ShopTypeEnum.JOIN_TRUSTEESHIP_SHOP.getStoreProperties())) {
                            failJoinList.add(readDto.getChannelCode() + "-" + readDto.getStoreCode());
                        }
                    }
                }
            }
            if (failDirectlyList.size() > 0) {
                throw new RomeException(ResponseMsg.FAIL_2905.getCode(), ResponseMsg.FAIL_2905.getMsg() + failDirectlyList);
            }
            if (failJoinList.size() > 0) {
                throw new RomeException(ResponseMsg.FAIL_2906.getCode(), ResponseMsg.FAIL_2906.getMsg() + failJoinList);
            }
            //获取不重复
            List<String> provinceCodes = storeList.stream().filter(f -> ObjectUtil.isNotNull(f.getProvinceCode())).map(StoreDTO::getProvinceCode).distinct().collect(Collectors.toList());
            List<String> cityCodes = storeList.stream().filter(f -> ObjectUtil.isNotNull(f.getCityCode())).map(StoreDTO::getCityCode).distinct().collect(Collectors.toList());
            List<String> countyCodes = storeList.stream().filter(f -> ObjectUtil.isNotNull(f.getAreaCode())).map(StoreDTO::getAreaCode).distinct().collect(Collectors.toList());
            //根据code批量获取省市区信息
            if (provinceCodes.size() > 0) {
                provinceListByStore = baseDataFacade.listAreaInfoByCode(provinceCodes);
            }
            if (cityCodes.size() > 0) {
                cityListByStore = baseDataFacade.listAreaInfoByCode(cityCodes);
            }
            if (countyCodes.size() > 0) {
                countyListByStore = baseDataFacade.listAreaInfoByCode(countyCodes);
            }
        }
        //获取导入数据中去重后的商品code集合
        List<String> skuCodeList = dtoList.stream().filter(item -> ObjectUtil.isNotNull(item.getSkuCode())).map(SalesPlanOtherSimpleDTO::getSkuCode).distinct().collect(Collectors.toList());
        //转换为基础单位
        List<SkuUnitExtDTO> skuUnitList = itemCoreFacade.getSkuUnitByCodeAndType(skuCodeList, 5);
        ifTrue = skuUnitList.size() == skuCodeList.size();
        if (!ifTrue) {
            List<String> skuSt = skuUnitList.stream().map(SkuUnitExtDTO::getSkuCode).collect(Collectors.toList());
            List<String> list = skuCodeList.stream().filter(item -> !skuSt.contains(item)).collect(Collectors.toList());
            throw new RomeException(ResponseMsg.FAIL_2033.getCode(), ResponseMsg.FAIL_2033.getMsg() + list);
        }
        //根据商品code集合获取商品对应品类id集合(接口最多一次只能调100个)
        List<SkuInfosDTO> skus = new ArrayList<>();
        int perThreadHandleCount = 100;
        int countNum = 0;
        while (countNum < skuCodeList.size()) {
            countNum += perThreadHandleCount;
            List<String> dtos = ImmutableList.copyOf(skuCodeList.subList(countNum - perThreadHandleCount,
                    countNum < skuCodeList.size() ? countNum : skuCodeList.size()));
            List<SkuInfosDTO> skuInfos = itemCoreFacade.getAllCategoryIdBySkuCode(1, dtos.size(), dtos).getList();
            skus.addAll(skuInfos);
        }
        ifTrue = skus.size() == skuCodeList.size();
        if (!ifTrue) {
            List<String> skuSt = skus.stream().map(SkuInfosDTO::getSkuCode).collect(Collectors.toList());
            List<String> list = skuCodeList.stream().filter(item -> !skuSt.contains(item)).collect(Collectors.toList());
            throw new RomeException(ResponseMsg.FAIL_2032.getCode(), ResponseMsg.FAIL_2032.getMsg() + list);
        }
        List<Integer> ids = skus.stream().filter(f -> ObjectUtil.isNotNull(f.getCategoryId())).map(SkuInfosDTO::getCategoryId).distinct().collect(Collectors.toList());
        //查询出所有商品code对应的品类信息
        List<CategorySimpleDTO> categorys = itemCoreFacade.getAllCategoryByCategoryId(ids);
        List<SalesPlanOtherDTO> saleList = this.getSaleList(dtoList, skus, categorys, provinceList, cityNameList, storeList,
                provinceListByStore, cityListByStore, countyListByStore,
                provinceNameListByCity, skuUnitList);
        List<SalesPlanOtherDTO> sales = new ArrayList<>();
        IdWorker idWorker = new IdWorker();
        saleList.parallelStream().collect(Collectors.groupingBy(o -> (o.getChannelCode() + o.getProvinceCode() + o.getPlanStartDate() + o.getSkuCode() + o.getType() + (ObjectUtil.isNotEmpty(o.getStoreCode()) ? o.getStoreCode() : "") + (ObjectUtil.isNotEmpty(o.getCityCode()) ? o.getCityCode() : "") + (ObjectUtil.isNotEmpty(o.getCountyCode()) ? o.getCountyCode() : "")), Collectors.toList())).forEach((k, v) -> {
            Long id = idWorker.getId();
            //优惠券不添加到总量里
            if (v.get(0).getSkuName().contains("优惠券")) {
                BigDecimal qty = v.stream().map(SalesPlanOtherDTO::getCouponQty).reduce(BigDecimal.ZERO, BigDecimal::add);
                v.get(0).setSalesPlanOtherNo(id + "");
                v.get(0).setCouponQty(qty);
            } else {
                BigDecimal reduce = v.stream().map(SalesPlanOtherDTO::getChannelConfirmedQty).reduce(BigDecimal.ZERO, BigDecimal::add);
                v.get(0).setSalesPlanOtherNo(id + "");
                v.get(0).setPlanQty(reduce);
                v.get(0).setChannelConfirmedQty(reduce);
                v.get(0).setAllchannelConfirmedQty(reduce);
            }
            //营销计划导入默认为可取消
            v.get(0).setSynStatus(CommonConstants.ONE);
            //v.get(0).setPlanImportDate(new Date());
            sales.add(v.get(0));
        });
        List<SalesPlanOtherDTO> salesList = new ArrayList<>();
        salesList = sales;
        Integer size = 0;
        List<UnitCodeExtParamDTO> paramList = new ArrayList<>();
        for (SalesPlanOtherSimpleDTO simple : dtoList) {
            UnitCodeExtParamDTO param = new UnitCodeExtParamDTO();
            param.setSkuCode(simple.getSkuCode());
            param.setUnitName(simple.getUnit());
            paramList.add(param);
        }
        //去掉重复数据
        HashSet set = new HashSet(paramList);
        paramList.clear();
        paramList.addAll(set);
        List<SkuUnitDTO> skuUnitaList = itemCoreFacade.getUtilInfoBySkuCode(paramList);
        List<SkuUnitDTO> skuUnitListb = new ArrayList<>();
        //去重
        skuUnitaList.parallelStream().collect(Collectors.groupingBy(o -> (o.getSkuCode() + o.getUnitName() + o.getUnitCode() + o.getScale()), Collectors.toList())).forEach((k, v) -> {
            skuUnitListb.add(v.get(0));
        });
        this.calculationProBySale(salesList, skuUnitListb);
        //处理单位(查出销售单位换算比例)
        List<SkuUnitDTO> skuUnitLista = itemCoreFacade.getConversionRatio(skuCodeList, SkuUnitTypeEnum.SALES_UNIT.getUnitType());
        this.calculationProBySale(salesList, skuUnitLista);
        //处理单位(查出基础单位换算比例)
        List<SkuUnitDTO> skuUnitListc = itemCoreFacade.getConversionRatio(skuCodeList, SkuUnitTypeEnum.BASIS_UNIT.getUnitType());
        this.calculationPro(salesList, skuUnitListc);
        List<Date> startDateList = salesList.stream().map(SalesPlanOtherDTO::getPlanStartDate).distinct().collect(Collectors.toList());
        List<Date> endDateList = salesList.stream().map(SalesPlanOtherDTO::getPlanEndDate).distinct().collect(Collectors.toList());
        //获取重复数据
        List<SalesPlanEsEntity> dateLists = dealData(salesList, Collections.min(startDateList), Collections.max(endDateList));
        if (CollectionUtils.isNotEmpty(dateLists)) {
            List<SalesPlanEsEntity> updateList = new ArrayList<>();
            List<SalesPlanOtherDTO> insertList = new ArrayList<>();
            for (SalesPlanOtherDTO dtoa : salesList) {
                List<SalesPlanEsEntity> repeats = dateLists.stream().filter(item ->
                        item.getActivity_no().equals(dtoa.getSalesPlanActivityNo()) &&
                        item.getChannel().equals(dtoa.getChannelCode()) &&
                                item.getPlan_type().equals(dtoa.getType()) &&
                                item.getProvince_code().equals(dtoa.getProvinceCode()) &&
                                (ObjectUtil.isNull(dtoa.getCityCode()) ? true : (ObjectUtil.isNull(item.getCity_code()) ? false : item.getCity_code().equals(dtoa.getCityCode()))) &&
                                (ObjectUtil.isNull(dtoa.getStoreCode()) ? true : (ObjectUtil.isNull(item.getNode_id()) ? false : item.getNode_id().equals(dtoa.getStoreCode()))) &&
                                item.getSku_key().equals(dtoa.getSkuCode()) &&
                                DateUtil.parseDate(item.getStart_date()).compareTo(dtoa.getPlanStartDate()) == 0)
                        .collect(Collectors.toList());
                //说明同一个省份下有多条记录
                if (repeats.size() > 1) {
                    //如果只有省
                    if (ObjectUtil.isNull(dtoa.getCityCode()) && ObjectUtil.isNull(dtoa.getStoreCode())) {
                        //过滤去掉城市和门店为空的省份数据
                        repeats = repeats.stream().filter(repeat -> ObjectUtil.isNull(repeat.getCity_code())
                                && ObjectUtil.isNull(repeat.getNode_id())).collect(Collectors.toList());
                    }
                    //如果有省和城市
                    else if (ObjectUtil.isNotNull(dtoa.getCityCode()) && ObjectUtil.isNull(dtoa.getStoreCode())) {
                        //过滤去掉门店为空的数据
                        repeats = repeats.stream().filter(repeat -> ObjectUtil.isNull(repeat.getNode_id())).collect(Collectors.toList());
                    }
                }
                if (repeats.size() == 1) {
                    SalesPlanEsEntity dto = repeats.get(0);
                    dto.setPredict_sales(dtoa.getPlanQty());
                    dto.setConfirm_l3(dtoa.getChannelConfirmedQty());
                    dto.setConfirm_l4(dtoa.getAllchannelConfirmedQty());
                    //dto.setImport_date(DateUtil.formatDate(new Date()));
                    dto.setImport_date(DateUtil.formatDate(salesList.get(0).getPlanImportDate()));
                    updateList.add(dto);
                } else {
                    insertList.add(dtoa);
                }
            }
            if (updateList.size() > 0) {
                asyncUpdateOtherEsData1(updateList);
            }
            salesList = insertList;
            if (insertList.size() > 0) {
                asyncInsertOtherEsData(salesList);
            }
        } else {
            asyncInsertOtherEsData(salesList);
        }
        return Boolean.TRUE;

    }

    /**
     * 获取系统重复数据
     *
     * @param list
     * @return
     */
    public List<SalesPlanEsEntity> dealData(List<SalesPlanOtherDTO> list, Date start, Date end) {
        //开始时间
        String startDate;
        //结束时间
        String endDate;
        //计划导入
        if (start == null && end == null) {
            //获取当前周第二周到后五周的日期
            //List<Map<String, Date>> lastDateMap = MyDateUtil.getWeekDates(new Date(), CommonConstants.SIX);
            List<Map<String, Date>> lastDateMap = MyDateUtil.getWeekDates(list.get(0).getPlanImportDate(), CommonConstants.SIX);
            startDate = DateUtil.formatDate(lastDateMap.get(1).get("startTime"));
            endDate = DateUtil.formatDate(lastDateMap.get(5).get("startTime"));
        } else {
            //营销同步
            startDate = DateUtil.formatDate(start);
            endDate = DateUtil.formatDate(end);
        }
        List<SalesPlanEsEntity> esList = new ArrayList<>();
        //处理查询出来的数据
        //把查询的结果代入新的对象中，用于查询数据
        if (ObjectUtil.isNotEmpty(list)) {
            Map<String, List<SalesPlanOtherDTO>> mapList = list.stream().collect(Collectors.groupingBy(o -> (o.getChannelCode() + o.getType() + o.getSkuCode() + (ObjectUtil.isNotNull(o.getStoreCode()) ? o.getStoreCode() : "") + (ObjectUtil.isNotNull(o.getProvinceCode()) ? o.getProvinceCode() : "") + (ObjectUtil.isNotNull(o.getCityCode()) ? o.getCityCode() : "") + (ObjectUtil.isNotNull(o.getCountyCode()) ? o.getCountyCode() : ""))));
            List<SalesPlanOtherDTO> proList = new ArrayList<>();
            List<SalesPlanOtherDTO> cityList = new ArrayList<>();
            List<SalesPlanOtherDTO> storeList = new ArrayList<>();
            mapList.forEach((k, v) -> {
                SalesPlanOtherDTO otherDto = new SalesPlanOtherDTO();
                //如果市和门店都是空，区域只填了省
                if (StringUtils.isEmpty(v.get(0).getCityCode()) && StringUtils.isEmpty(v.get(0).getStoreCode())) {
                    proList.add(v.get(0));
                }
                //如果市不是空门店是空，区域只填了省、市
                if (!StringUtils.isEmpty(v.get(0).getCityCode()) && StringUtils.isEmpty(v.get(0).getStoreCode())) {
                    cityList.add(v.get(0));
                }
                //如果门店不是空，区域填了门店
                if (!StringUtils.isEmpty(v.get(0).getStoreCode())) {
                    storeList.add(v.get(0));
                }
            });
            proList.addAll(cityList);
            proList.addAll(storeList);
            //获取查询条件
            EsQueryDTO esQuery = getQuery(startDate, endDate, proList);
            List<String> channelList = list.stream().map(SalesPlanOtherDTO::getChannelCode).distinct().collect(Collectors.toList());
            esQuery.setChannelCodeList(channelList);
            List<String> typeList = list.stream().map(SalesPlanOtherDTO::getType).distinct().collect(Collectors.toList());
            esQuery.setTypeList(typeList);
            List<String> skuList = list.stream().map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.toList());
            List<SalesPlanSelectDTO> selectList = new ArrayList<>();
            for (String sku : skuList) {
                SalesPlanSelectDTO dto = new SalesPlanSelectDTO();
                dto.setCode(sku);
                dto.setLevel(CommonConstants.CATEGORY_LEVEL_FOUR);
                selectList.add(dto);
            }
            esQuery.setCategoryCodeList(selectList);
            esList = salesPlanOtherEsRepository.listPageQuery(esQuery);
        }
        return esList;
    }

    private EsQueryDTO getQuery(String startDate, String endDate, List<SalesPlanOtherDTO> proList) {
        EsQueryDTO esQuery = new EsQueryDTO();
        esQuery.setStartDate(startDate);
        esQuery.setEndDate(endDate);
        List<String> areaList = new ArrayList<>();
        proList.forEach(item -> {
            //只有省
            if (StringUtils.isEmpty(item.getCityCode()) && StringUtils.isEmpty(item.getStoreCode())) {
                areaList.add(item.getProvinceCode());
            }
            //只有省市
            else if (StringUtils.isNotEmpty(item.getCityCode()) && StringUtils.isEmpty(item.getStoreCode())) {
                areaList.add(item.getProvinceCode() + "/" + item.getCityCode());
            } else {
                //省市区门店
                areaList.add(item.getProvinceCode() + "/" + item.getCityCode() + "/" + item.getCountyCode() + "/" + item.getStoreCode());
            }
        });
        List<String> list = areaList.stream().distinct().collect(Collectors.toList());
        esQuery.setAreaCodeList(list);
        return esQuery;
    }

    /**
     * 单位换算（查询）
     *
     * @param resultList
     * @param skuUnitList
     * @return
     */
    private List<SalesPlanOtherInfoDTO> calculationProBySelect(List<SalesPlanOtherInfoDTO> resultList, List<SkuUnitDTO> skuUnitList) {
        if (CollectionUtils.isNotEmpty(skuUnitList) && CollectionUtils.isNotEmpty(resultList)) {
            skuUnitList.forEach(skuUnit -> {
                resultList.forEach(item -> {
                    List<BigDecimal> lastPlanQtys = new ArrayList<>();
                    List<BigDecimal> lastConfirmedQtys = new ArrayList<>();
                    List<BigDecimal> planQtys = new ArrayList<>();
                    List<BigDecimal> confirmedQtys = new ArrayList<>();
                    List<BigDecimal> subordinateConfirmedQtys = new ArrayList<>();
                    List<BigDecimal> planDifferences = new ArrayList<>();
                    if (item.getSkuCode().equals(skuUnit.getSkuCode())) {
                        item.getLastPlanQtys().forEach(qty -> {
                            lastPlanQtys.add((qty.compareTo(BigDecimal.ZERO) != 0 ? qty.divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO));
                        });
                        item.getLastConfirmedQtys().forEach(qty -> {
                            lastConfirmedQtys.add((qty.compareTo(BigDecimal.ZERO) != 0 ? qty.divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO));
                        });
                        item.getPlanQtys().forEach(qty -> {
                            planQtys.add((qty.compareTo(BigDecimal.ZERO) != 0 ? qty.divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO));
                        });
                        item.getConfirmedQtys().forEach(qty -> {
                            confirmedQtys.add((qty.compareTo(BigDecimal.ZERO) != 0 ? qty.divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO));
                        });
                        if (CollectionUtils.isNotEmpty(item.getSubordinateConfirmedQtys())) {
                            item.getSubordinateConfirmedQtys().forEach(qty -> {
                                subordinateConfirmedQtys.add((qty.compareTo(BigDecimal.ZERO) != 0 ? qty.divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO));
                            });
                        }
                        item.getPlanDifferences().forEach(qty -> {
                            planDifferences.add((qty.compareTo(BigDecimal.ZERO) != 0 ? qty.divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO));
                        });
                        item.setLastPlanQtys(lastPlanQtys);
                        item.setLastConfirmedQtys(lastConfirmedQtys);
                        item.setPlanQtys(planQtys);
                        item.setConfirmedQtys(confirmedQtys);
                        item.setSubordinateConfirmedQtys(subordinateConfirmedQtys);
                        item.setPlanDifferences(planDifferences);
                    }
                });
            });
        }
        return resultList;
    }

    /**
     * 设置查询条件
     *
     * @param boolQueryBuilder
     * @param field
     * @param values
     */
    private void setMultiConditions(BoolQueryBuilder boolQueryBuilder, String field, List<String> values) {
        if (values == null || values.size() == 0) {
            return;
        }
        BoolQueryBuilder subBoolQueryBuilder = boolQuery();
        values.forEach(v -> subBoolQueryBuilder.should(QueryBuilders.matchQuery(field, v)));
        boolQueryBuilder.must(boolQueryBuilder);
    }

    /**
     * 批量修改其他渠道计划状态（营销计划）
     *
     * @param numbers
     */
    @Override
    public Boolean updatePlanOtherType(List<String> numbers) {
        if (CollectionUtils.isEmpty(numbers)) {
            throw new RomeException(ResponseMsg.PARAM_ERROR_2017.getCode(), ResponseMsg.PARAM_ERROR_2017.getMsg());
        }
        EsQueryDTO dto = new EsQueryDTO();
        dto.setActivityCodeList(numbers);
        //根据活动计划编号获取可以修改的数据
        List<SalesPlanEsEntity> dtoList = salesPlanOtherEsRepository.listPageQuery(dto);
        if (dtoList.size() == 0) {
            throw new RomeException(ResponseMsg.PARAM_ERROR_2022.getCode(), ResponseMsg.PARAM_ERROR_2022.getMsg());
        }
        //筛选出已经取消的销售计划
        List<String> noList = dtoList.stream().filter(item -> ObjectUtil.isNotNull(item.getCancel_status()) && CommonConstants.TWO.equals(item.getCancel_status())).map(SalesPlanEsEntity::getActivity_no).distinct().collect(Collectors.toList());
        if (noList.size() > 0) {
            throw new RomeException(ResponseMsg.PARAM_ERROR_2034.getCode(), ResponseMsg.PARAM_ERROR_2034.getMsg() + noList);
        }
        //筛选出已同步到大数据的销售计划，不能取消
        List<String> statusLists = dtoList.stream().filter(item -> ObjectUtil.isNotNull(item.getCancel_status()) && CommonConstants.ZERO.equals(item.getCancel_status())).map(SalesPlanEsEntity::getActivity_no).distinct().collect(Collectors.toList());
        if (statusLists.size() > 0) {
            throw new RomeException(ResponseMsg.PARAM_ERROR_2035.getCode(), ResponseMsg.PARAM_ERROR_2035.getMsg() + statusLists);
        }
        dtoList.forEach(item -> {
            item.setCancel_status(CommonConstants.TWO);
        });
        asyncUpdateOtherEsData1(dtoList);
        return Boolean.TRUE;

    }

    /**
     * 解析返回结果
     * 返回哪些指标，要根据条件筛选 TODO
     *
     * @param aggregations
     * @return
     */
    private List<SalesPlanOtherInfoDTO> dealResult(Aggregations aggregations) {
        List<SalesPlanOtherInfoDTO> result = new ArrayList<>();
        //如果要返回分页数据，需要自己实现伪分页
        // 固定解析四级分组
        Map<String, Aggregations> channelAggregationsMap = getSubAggregations(aggregations, GROUP_CHANNEL_CODE);
        // 定义返回对象
        SalesPlanOtherInfoDTO dto = null;
        for (Map.Entry<String, Aggregations> channelEntry : channelAggregationsMap.entrySet()) {
            Map<String, Aggregations> planTypeAggregationsMap = getSubAggregations(channelEntry.getValue(), GROUP_PLAN_TYPE);
            for (Map.Entry<String, Aggregations> planTypeEntry : planTypeAggregationsMap.entrySet()) {

                Map<String, Aggregations> areaAggregationsMap = getSubAggregations(planTypeEntry.getValue(), GROUP_AREA);
                for (Map.Entry<String, Aggregations> areaEntry : areaAggregationsMap.entrySet()) {
                    // 地区，可能需要转换
                    String area = areaEntry.getKey();
                    Map<String, Aggregations> skuAggregationsMap = getSubAggregations(areaEntry.getValue(), GROUP_SKU_CODE);
                    // sku维度拆分对象
                    dto = new SalesPlanOtherInfoDTO();
                    for (Map.Entry<String, Aggregations> skuEntry : skuAggregationsMap.entrySet()) {
                        String skuCode = skuEntry.getKey();
                        Map<Long, Aggregations> dateAggregationsMap = getSubAggregations2(skuEntry.getValue(), GROUP_DATE);
                        List<BigDecimal> planQtySumList = new ArrayList<>();
                        for (Map.Entry<Long, Aggregations> dateEntry : dateAggregationsMap.entrySet()) {
                            // 日期
                            LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(
                                    dateEntry.getKey() / 1000, 0, ZoneOffset.ofHours(8));
//                            dto.setPlanStartDate(localDateTime.toLocalDate().toString());
                            Map<String, Aggregation> sumMap = dateEntry.getValue().asMap();
                            InternalSum planQtySum = (InternalSum) sumMap.get("planQtySum");
                            planQtySumList.add(BigDecimal.valueOf(planQtySum.getValue()));
                            //                        InternalSum prePlanQtySum = (InternalSum) sumMap.get("prePlanQtySum");
                        }
                        dto.setConfirmedQtys(planQtySumList);
                        dto.setSkuCode(skuCode);
                    }
                    dto.setArea(area);
                }
                //计划类型
                if (dto != null) {
                    dto.setType(planTypeEntry.getKey());
                }
            }
            if (dto != null) {
                dto.setChannelCode(channelEntry.getKey());
                result.add(dto);
            }
        }
        return result;
    }

    /**
     * 获取下级聚合数据
     *
     * @param aggregations
     * @param subKey
     * @return 返回map，key是下级指标，值是聚合Aggregations对象
     */
    private Map<String, Aggregations> getSubAggregations(Aggregations aggregations, String subKey) {
        Map<String, Aggregation> aggregationMap = aggregations.asMap();
        StringTerms stringTerms = (StringTerms) aggregationMap.get(subKey);
        List<StringTerms.Bucket> buckets = stringTerms.getBuckets();
        return buckets.stream().collect(Collectors.toMap(bucket -> (String) bucket.getKey(), InternalTerms.Bucket::getAggregations));
    }

    private Map<Long, Aggregations> getSubAggregations2(Aggregations aggregations, String subKey) {
        Map<String, Aggregation> aggregationMap = aggregations.asMap();
        LongTerms longTerms = (LongTerms) aggregationMap.get(subKey);
        List<LongTerms.Bucket> buckets = longTerms.getBuckets();
        return buckets.stream().collect(Collectors.toMap(bucket -> (Long) bucket.getKey(), InternalTerms.Bucket::getAggregations));
    }

    /**
     * 更新数据到ES
     *
     * @param updateList
     */
    public void asyncUpdateOtherEsData(List<SalesPlanOtherDTO> updateList) {
        if (CollectionUtil.isEmpty(updateList)) {
            return;
        }
        List<IndexQuery> indexQueryList = new ArrayList<>();
        for (SalesPlanOtherDTO salesPlanOtherDTO : updateList) {
            String salesPlanOtherNo = salesPlanOtherDTO.getSalesPlanOtherNo();
            NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                    .withQuery(matchQuery("business_no", salesPlanOtherNo))
                    .build();
            List<String> idList = elasticsearchTemplate.queryForIds(searchQuery);
            if (idList != null && idList.size() == 1) {
                SalesPlanEsEntity esEntity = convertEsInsertEntity(salesPlanOtherDTO);
                esEntity.setId(idList.get(0));
                indexQueryList.add(new IndexQueryBuilder().withObject(esEntity).build());
            }
        }
        if (indexQueryList.size() > 0) {
            elasticsearchTemplate.bulkIndex(indexQueryList);
            //清空缓存（销售计划、其他渠道计划）
            commonService.clearCache(CommonConstants.REDIS_CACHE_SALE_PLAN);
            commonService.clearCache(CommonConstants.REDIS_CACHE_OTHER_CHANNEL);
        }
    }

    public void asyncUpdateOtherEsData1(List<SalesPlanEsEntity> updateList) {
        if (CollectionUtil.isEmpty(updateList)) {
            return;
        }
        List<IndexQuery> indexQueryList = new ArrayList<>();
        for (SalesPlanEsEntity salesPlanEsEntity : updateList) {
            salesPlanEsEntity.setUpdate_time(LocalDateTime.now());
            indexQueryList.add(new IndexQueryBuilder().withObject(salesPlanEsEntity).build());
        }
        if (indexQueryList.size() > 0) {
            elasticsearchTemplate.bulkIndex(indexQueryList);
            elasticsearchTemplate.refresh(BigDataEsConstants.INDEX_NAME_PLAN_SALES_PLAN);
            //清空缓存（销售计划、其他渠道计划）
            commonService.clearCache(CommonConstants.REDIS_CACHE_SALE_PLAN);
            commonService.clearCache(CommonConstants.REDIS_CACHE_OTHER_CHANNEL);
        }

    }

    /**
     * 定时修改确认状态
     */
    @Transactional(rollbackFor = Exception.class)
    public void asyncUpdateOtherEsStatus() {
        final long SCROLL_TIMEOUT = 5 * 60 * 1000;
        final Integer status = SalesConfirmStatusEnum.CONFIRMED.getType();
        final Integer unconfirmedStatus = SalesConfirmStatusEnum.UNCONFIRMED.getType();
        // 非直营预测，当前周期数据，遍历修改状态
        int pageNum = 0;
        int pageSize = 1000;
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //查询状态不为直营预测，确认状态为未确认的数据
        boolQueryBuilder.must(matchQuery(EsConmulEnum.CONFIRM_STATUS.getFName(), SalesConfirmStatusEnum.UNCONFIRMED.getType()));
        boolQueryBuilder.mustNot(matchQuery(EsConmulEnum.PLAN_TYPE.getFName(), SalesPlanTypeEnum.PLAN_SEVENTEEN.getType()));
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(PageRequest.of(pageNum, pageSize));
        ScrolledPage<SalesPlanEsEntity> scroll = (ScrolledPage<SalesPlanEsEntity>) elasticsearchTemplate
                .startScroll(SCROLL_TIMEOUT, queryBuilder.build(), SalesPlanEsEntity.class);
        while (scroll.hasContent()) {
            List<IndexQuery> indexQueryList = new ArrayList<>();
            scroll.getContent().forEach(entity -> {
                // 修改未确认的状态2为确认状态1
                if (entity.getConfirm_status_l4() == null || unconfirmedStatus.equals(entity.getConfirm_status_l4())) {
                    entity.setConfirm_status_l4(status);
                    entity.setUpdate_time(LocalDateTime.now());
                    indexQueryList.add(new IndexQueryBuilder().withObject(entity).build());
                }
            });
            elasticsearchTemplate.bulkIndex(indexQueryList);
            scroll = (ScrolledPage<SalesPlanEsEntity>) elasticsearchTemplate.continueScroll(
                    scroll.getScrollId(), SCROLL_TIMEOUT, SalesPlanEsEntity.class);
        }
        //清空缓存（销售计划、其他渠道计划）
        commonService.clearCache(CommonConstants.REDIS_CACHE_SALE_PLAN);
        commonService.clearCache(CommonConstants.REDIS_CACHE_OTHER_CHANNEL);
    }

    /**
     * 定时修改营销中心取消状态
     */
    @Transactional(rollbackFor = Exception.class)
    public void asyncUpdateOtherEsStatusYx() {
        final long SCROLL_TIMEOUT = 5 * 60 * 1000;
        final Integer noCancelStatus = SalesCancelStatusEnum.NOCANCEL.getType();
        final Integer cancelStatus = SalesCancelStatusEnum.CANCANCEL.getType();
        // 非直营预测，当前周期数据，遍历修改状态
        int pageNum = 0;
        int pageSize = 1000;
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //查询状态不为直营预测，取消状态为可取消的数据
        boolQueryBuilder.must(matchQuery(EsConmulEnum.CANCEL_STATUS.getFName(), SalesCancelStatusEnum.CANCANCEL.getType()));
        boolQueryBuilder.mustNot(matchQuery(EsConmulEnum.PLAN_TYPE.getFName(), SalesPlanTypeEnum.PLAN_SEVENTEEN.getType()));
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withPageable(PageRequest.of(pageNum, pageSize));
        ScrolledPage<SalesPlanEsEntity> scroll = (ScrolledPage<SalesPlanEsEntity>) elasticsearchTemplate
                .startScroll(SCROLL_TIMEOUT, queryBuilder.build(), SalesPlanEsEntity.class);
        while (scroll.hasContent()) {
            List<IndexQuery> indexQueryList = new ArrayList<>();
            scroll.getContent().forEach(entity -> {
                // 营销中心可取消的状态变成不可取消
                if (entity.getCancel_status() == null || cancelStatus.equals(entity.getCancel_status())) {
                    entity.setCancel_status(noCancelStatus);
                    entity.setUpdate_time(LocalDateTime.now());
                    indexQueryList.add(new IndexQueryBuilder().withObject(entity).build());
                }
            });
            elasticsearchTemplate.bulkIndex(indexQueryList);
            scroll = (ScrolledPage<SalesPlanEsEntity>) elasticsearchTemplate.continueScroll(
                    scroll.getScrollId(), SCROLL_TIMEOUT, SalesPlanEsEntity.class);
        }
        //清空缓存（销售计划、其他渠道计划）
        commonService.clearCache(CommonConstants.REDIS_CACHE_SALE_PLAN);
        commonService.clearCache(CommonConstants.REDIS_CACHE_OTHER_CHANNEL);
    }

    /**
     * 更新数据中为空的仓库信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateOtherEsWarehouseCode() {
        //记录获取不到仓库的渠道、区域信息
        List<String> errorLogs = new ArrayList<>();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //查询状态不为直营预测，仓库字段为null的数据
        boolQueryBuilder.mustNot(existsQuery(EsConmulEnum.WAREHOUSE_KEYWORD.getFName()));
        boolQueryBuilder.mustNot(matchQuery(EsConmulEnum.PLAN_TYPE.getFName(), SalesPlanTypeEnum.PLAN_SEVENTEEN.getType()));
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withIndices(BigDataEsConstants.INDEX_NAME_PLAN_SALES_PLAN)
                .withPageable(PageRequest.of(CommonConstants.ZERO, CommonConstants.PLAN_OTHER_IMPORT_MAX))
                .build();
        List<SalesPlanEsEntity> esList = elasticsearchTemplate.queryForList(query, SalesPlanEsEntity.class);
        if (CollectionUtil.isEmpty(esList)) {
            return;
        }
        List<SearchSourceToCQueryDTO> wharehouseList = getWarehouseList(null, esList);
        esList.forEach(items -> {
            List<SearchSourceToCQueryDTO> wharehouseCodeList = wharehouseList.stream()
                    .filter(item -> item.getChannelCode().equals(items.getChannel())
                            && item.getProvinceCode().equals(items.getProvince_code())
                            && (ObjectUtil.isNotNull(item.getCityCode()) ? item.getCityCode().equals(items.getCity_code()) : true)
                            && (ObjectUtil.isNotNull(item.getCounty()) ? item.getCounty().equals(items.getDistrict_code()) : true)).collect(Collectors.toList());
            if (wharehouseCodeList.size() == CommonConstants.ONE) {
                items.setDeliver_id(wharehouseCodeList.get(0).getWarehouseCode());
            } else if (wharehouseCodeList.size() > CommonConstants.ONE) {
                //需要根据优先级获取
                List<SearchSourceToCQueryDTO> sortedList = wharehouseCodeList.stream().sorted(
                        Comparator.comparing(SearchSourceToCQueryDTO::getPority).reversed()).collect(Collectors.toList());
                items.setDeliver_id(sortedList.get(0).getWarehouseCode());
            } else {
                errorLogs.add("渠道code" + items.getChannel() + "省份code:" + items.getProvince_code() + "，市code：" + items.getCity_code() + "，区code：" + items.getDistrict_code() + "对应不到仓库");
            }
        });
        //记录错误日志
        if (errorLogs.size() > 0) {
            log.error(errorLogs.stream().distinct().collect(Collectors.toList()).toString());
        }
        asyncUpdateOtherEsData1(esList);
    }

    /**
     * 根据对象集合获取渠道加区域获取的仓库
     *
     * @param insertList
     * @param esList
     * @return
     */
    public List<SearchSourceToCQueryDTO> getWarehouseList(List<SalesPlanOtherDTO> insertList, List<SalesPlanEsEntity> esList) {
        List<SearchSourceToCQueryDTO> queryDtoList = new ArrayList<>();
       if (null == esList) {
        //获取所有不重复的省（只填到省）
        List<SalesPlanOtherDTO> provinceList = insertList.stream().filter(item -> ObjectUtil.isNull(item.getCityCode()) && ObjectUtil.isNull(item.getStoreCode())).distinct().collect(Collectors.toList());
        if (provinceList.size() > 0) {
            for (SalesPlanOtherDTO dto : provinceList) {
                SearchSourceToCQueryDTO queryDto = new SearchSourceToCQueryDTO();
                queryDto.setChannelCode(dto.getChannelCode());
                queryDto.setProvinceCode(dto.getProvinceCode());
                queryDtoList.add(queryDto);
            }
        }
        //获取所有不重复的市（填到市）
        List<SalesPlanOtherDTO> cityList = insertList.stream().filter(item -> ObjectUtil.isNotNull(item.getCityCode()) && ObjectUtil.isNull(item.getStoreCode())).distinct().collect(Collectors.toList());
        if (cityList.size() > 0) {
            for (SalesPlanOtherDTO dto : cityList) {
                SearchSourceToCQueryDTO queryDto = new SearchSourceToCQueryDTO();
                queryDto.setChannelCode(dto.getChannelCode());
                queryDto.setProvinceCode(dto.getProvinceCode());
                queryDto.setCityCode(dto.getCityCode());
                queryDtoList.add(queryDto);
            }
        }
        //获取所有不重复的门店（填到门店）
        List<SalesPlanOtherDTO> storeList = insertList.stream().filter(item -> ObjectUtil.isNotNull(item.getStoreCode())).distinct().collect(Collectors.toList());
        if (storeList.size() > 0) {
            for (SalesPlanOtherDTO dto : storeList) {
                SearchSourceToCQueryDTO queryDto = new SearchSourceToCQueryDTO();
                queryDto.setChannelCode(dto.getChannelCode());
                queryDto.setProvinceCode(dto.getProvinceCode());
                queryDto.setCityCode(dto.getCityCode());
                queryDto.setCounty(dto.getCountyCode());
                queryDtoList.add(queryDto);
            }
        }
       } else {
           //获取所有不重复的省（只填到省）
           List<SalesPlanEsEntity> provinceList = esList.stream().filter(item -> ObjectUtil.isNull(item.getCity_code()) && ObjectUtil.isNull(item.getNode_id())).distinct().collect(Collectors.toList());
           if (provinceList.size() > 0) {
               for (SalesPlanEsEntity dto : provinceList) {
                   SearchSourceToCQueryDTO queryDto = new SearchSourceToCQueryDTO();
                   queryDto.setChannelCode(dto.getChannel());
                   queryDto.setProvinceCode(dto.getProvince_code());
                   queryDtoList.add(queryDto);
               }
           }
           //获取所有不重复的市（填到市）
           List<SalesPlanEsEntity> cityList = esList.stream().filter(item -> ObjectUtil.isNotNull(item.getCity_code()) && ObjectUtil.isNull(item.getNode_id())).distinct().collect(Collectors.toList());
           if (cityList.size() > 0) {
               for (SalesPlanEsEntity dto : cityList) {
                   SearchSourceToCQueryDTO queryDto = new SearchSourceToCQueryDTO();
                   queryDto.setChannelCode(dto.getChannel());
                   queryDto.setProvinceCode(dto.getProvince_code());
                   queryDto.setCityCode(dto.getCity_code());
                   queryDtoList.add(queryDto);
               }
           }
           //获取所有不重复的门店（填到门店）
           List<SalesPlanEsEntity> storeList = esList.stream().filter(item -> ObjectUtil.isNotNull(item.getNode_id())).distinct().collect(Collectors.toList());
           if (storeList.size() > 0) {
               for (SalesPlanEsEntity dto : storeList) {
                   SearchSourceToCQueryDTO queryDto = new SearchSourceToCQueryDTO();
                   queryDto.setChannelCode(dto.getChannel());
                   queryDto.setProvinceCode(dto.getProvince_code());
                   queryDto.setCityCode(dto.getCity_code());
                   queryDto.setCounty(dto.getDistrict_code());
                   queryDtoList.add(queryDto);
               }
           }
       }
        queryDtoList = queryDtoList.stream().distinct().collect(Collectors.toList());
        return nateWorkFacade.searchToCSource(queryDtoList);
    }

    /**
     * 插入数据到ES
     *
     * @param insertList
     */
    public void asyncInsertOtherEsData(List<SalesPlanOtherDTO> insertList) {
        if (CollectionUtil.isEmpty(insertList)) {
            return;
        }
        try {
            avgPriceMap = new HashMap<>();
            List<IndexQuery> indexQueryList = new ArrayList<>();
            List<SearchSourceToCQueryDTO> wharehouseList = getWarehouseList(insertList, null);
            //记录获取不到仓库的渠道、区域信息
            List<String> errorLogs = new ArrayList<>();
            // 转换成es数据实体集合
            List<SalesPlanEsEntity> esEntityList = insertList.stream().map(dto -> {
                //获取与新增数据对应的
                List<SearchSourceToCQueryDTO> wharehouseCodeList = wharehouseList.stream()
                        .filter(item -> item.getChannelCode().equals(dto.getChannelCode())
                                && item.getProvinceCode().equals(dto.getProvinceCode())
                                && (ObjectUtil.isNotNull(item.getCityCode()) ? item.getCityCode().equals(dto.getStoreCode()) : true)
                                && (ObjectUtil.isNotNull(item.getCounty()) ? item.getCounty().equals(dto.getCountyCode()) : true)).collect(Collectors.toList());
                SalesPlanEsEntity esEntity = convertEsInsertEntity(dto);
                if (wharehouseCodeList.size() == CommonConstants.ONE) {
                    esEntity.setDeliver_id(wharehouseCodeList.get(0).getWarehouseCode());
                } else if (wharehouseCodeList.size() > CommonConstants.ONE) {
                    //需要根据优先级获取
                    List<SearchSourceToCQueryDTO> sortedList = wharehouseCodeList.stream().sorted(
                            Comparator.comparing(SearchSourceToCQueryDTO::getPority).reversed()).collect(Collectors.toList());
                    esEntity.setDeliver_id(sortedList.get(0).getWarehouseCode());
                } else {
                    errorLogs.add("渠道code" + dto.getChannelCode() + "省份code:" + dto.getProvinceCode() + "，市code：" + dto.getCityCode() + "，区code：" + dto.getCountyCode() + "对应不到仓库");
                }
                esEntity.setCreate_time(LocalDateTime.now());
                return esEntity;
            }).collect(Collectors.toList());
            //记录错误日志
            log.error(errorLogs.stream().distinct().collect(Collectors.toList()).toString());
            //设置价格
            List<SkuPriceDTO> skuPriceList = new ArrayList<>();
            insertList.forEach(item -> {
                SkuPriceDTO dto = new SkuPriceDTO();
                dto.setSkuCode(item.getSkuCode());
                dto.setSaleUnitCode(item.getUnitCode());
                skuPriceList.add(dto);
            });
            //去重
            List<SkuPriceDTO> priceList = skuPriceList.stream().distinct().collect(Collectors.toList());
            Map<String, BigDecimal> priceMap = redisCacheService.getSkuAveragePrice(priceList);
            for (SalesPlanEsEntity salesPlanEsEntity : esEntityList) {
                //价格取不到默认为0
                salesPlanEsEntity.setAveragePrice(priceMap.get(salesPlanEsEntity.getSku_key() + salesPlanEsEntity.getUnit()) == null ? BigDecimal.ZERO
                        : priceMap.get(salesPlanEsEntity.getSku_key() + salesPlanEsEntity.getUnit()));
                // 确认量空的话默认0
                salesPlanEsEntity.setConfirm_l4(salesPlanEsEntity.getConfirm_l4() == null ? BigDecimal.ZERO
                        : salesPlanEsEntity.getConfirm_l4());
                // 确认状态空的话默认未确认
                salesPlanEsEntity.setConfirm_status_l4(salesPlanEsEntity.getConfirm_status_l4() == null
                        ? SalesConfirmStatusEnum.UNCONFIRMED.getType() : salesPlanEsEntity.getConfirm_status_l4());
                // // 安全库存和当前实时库存默认给0
                // salesPlanEsEntity.setSs(BigDecimal.ZERO);
                // salesPlanEsEntity.setSaleInventory(BigDecimal.ZERO);
                indexQueryList.add(new IndexQueryBuilder().withObject(salesPlanEsEntity).build());
            }
            if (indexQueryList.size() > 0) {
                elasticsearchTemplate.bulkIndex(indexQueryList);
                elasticsearchTemplate.refresh(BigDataEsConstants.INDEX_NAME_PLAN_SALES_PLAN);
                //清空缓存（销售计划、其他渠道计划）
                commonService.clearCache(CommonConstants.REDIS_CACHE_SALE_PLAN);
                commonService.clearCache(CommonConstants.REDIS_CACHE_OTHER_CHANNEL);
            }
        } catch (Exception e) {
            log.error("新增其他渠道计划数据异常:", e);
        } finally {
            // 清空avgPriceMap
            avgPriceMap = null;
        }
    }


    /**
     * dto 转成es 实体
     *
     * @param salesPlanOtherDTO
     * @return
     */
    private SalesPlanEsEntity convertEsInsertEntity(SalesPlanOtherDTO salesPlanOtherDTO) {
        SalesPlanEsEntity esEntity = new SalesPlanEsEntity();
        esEntity.setBusiness_no(salesPlanOtherDTO.getSalesPlanOtherNo());
        esEntity.setActivity_no(salesPlanOtherDTO.getSalesPlanActivityNo());
        esEntity.setPlan_type(salesPlanOtherDTO.getType());
        esEntity.setChannel(salesPlanOtherDTO.getChannelCode());
        esEntity.setArea(getJoinedArea(salesPlanOtherDTO.getProvinceCode()
                , salesPlanOtherDTO.getCityCode(), salesPlanOtherDTO.getCountyCode(), salesPlanOtherDTO.getStoreCode()));
        esEntity.setProvince_code(salesPlanOtherDTO.getProvinceCode());
        esEntity.setCity_code(salesPlanOtherDTO.getCityCode());
        esEntity.setDistrict_code(salesPlanOtherDTO.getCountyCode());
        esEntity.setCate_l2(salesPlanOtherDTO.getPriCategoryCode());
        esEntity.setCate_l3(salesPlanOtherDTO.getSecCategoryCode());
        esEntity.setCate_l4(salesPlanOtherDTO.getTerCategoryCode());
        esEntity.setSku_key(salesPlanOtherDTO.getSkuCode());
        esEntity.setUnit(salesPlanOtherDTO.getUnitCode());
        esEntity.setNode_id(salesPlanOtherDTO.getStoreCode());
        esEntity.setPredict_sales(salesPlanOtherDTO.getPlanQty());
        esEntity.setLast_predict_sales(salesPlanOtherDTO.getLastPlanQty());
        esEntity.setConfirm_l3(salesPlanOtherDTO.getChannelConfirmedQty());
        esEntity.setConfirm_l4(salesPlanOtherDTO.getAllchannelConfirmedQty());
        // other没有多级确认，只存4级字段
        esEntity.setConfirm_status_l4(status2Str(salesPlanOtherDTO.getStatus()));
        esEntity.setCancel_status(salesPlanOtherDTO.getSynStatus());
        esEntity.setLast_confirm_l3(salesPlanOtherDTO.getChannelLastConfirmedQty());
        esEntity.setLast_confirm_l4(salesPlanOtherDTO.getAllchannelLastConfirmedQty());

        esEntity.setStart_date(ObjectUtil.isNull(salesPlanOtherDTO.getPlanStartDate()) ? null : DateUtil.formatDate(salesPlanOtherDTO.getPlanStartDate()));
        esEntity.setEnd_date(ObjectUtil.isNull(salesPlanOtherDTO.getPlanEndDate()) ? null : DateUtil.formatDate(salesPlanOtherDTO.getPlanEndDate()));
        esEntity.setImport_date(ObjectUtil.isNull(salesPlanOtherDTO.getPlanImportDate()) ? null : DateUtil.formatDate(salesPlanOtherDTO.getPlanImportDate()));
        return esEntity;
    }

    private SalesPlanOtherDTO convertEsToDtoEntity(SalesPlanEsEntity salesPlanEsEntity) {
        SalesPlanOtherDTO dtoEntity = new SalesPlanOtherDTO();
        dtoEntity.setSalesPlanOtherNo(salesPlanEsEntity.getBusiness_no());
        dtoEntity.setType(salesPlanEsEntity.getPlan_type());
        dtoEntity.setChannelCode(salesPlanEsEntity.getChannel());
        dtoEntity.setProvinceCode(salesPlanEsEntity.getProvince_code());
        dtoEntity.setCityCode(salesPlanEsEntity.getCity_code());
        dtoEntity.setCountyCode(salesPlanEsEntity.getDistrict_code());
        dtoEntity.setPriCategoryCode(salesPlanEsEntity.getCate_l2());
        dtoEntity.setSecCategoryCode(salesPlanEsEntity.getCate_l3());
        dtoEntity.setTerCategoryCode(salesPlanEsEntity.getCate_l4());
        dtoEntity.setSkuCode(salesPlanEsEntity.getSku_key());
        dtoEntity.setUnitCode(salesPlanEsEntity.getUnit());
        dtoEntity.setStoreCode(salesPlanEsEntity.getNode_id());
        dtoEntity.setPlanQty(salesPlanEsEntity.getPredict_sales());
        dtoEntity.setLastPlanQty(salesPlanEsEntity.getLast_predict_sales());
        dtoEntity.setChannelConfirmedQty(salesPlanEsEntity.getConfirm_l3());
        dtoEntity.setAllchannelConfirmedQty(salesPlanEsEntity.getConfirm_l4());
        // other没有多级确认，只存4级字段
        dtoEntity.setStatus(salesPlanEsEntity.getConfirm_status_l4());
        dtoEntity.setSynStatus(salesPlanEsEntity.getCancel_status());
        dtoEntity.setChannelLastConfirmedQty(salesPlanEsEntity.getLast_confirm_l3());
        dtoEntity.setAllchannelLastConfirmedQty(salesPlanEsEntity.getLast_confirm_l4());
        dtoEntity.setPlanStartDate(ObjectUtil.isNull(salesPlanEsEntity.getStart_date()) ? null : DateUtil.parseDate(salesPlanEsEntity.getStart_date()));
        dtoEntity.setPlanEndDate(ObjectUtil.isNull(salesPlanEsEntity.getEnd_date()) ? null : DateUtil.parseDate(salesPlanEsEntity.getEnd_date()));
        dtoEntity.setPlanImportDate(ObjectUtil.isNull(salesPlanEsEntity.getImport_date()) ? null : DateUtil.parseDate(salesPlanEsEntity.getImport_date()));
        return dtoEntity;
    }

    private String getJoinedArea(String province, String city, String country, String store) {
        if (StringUtils.isEmpty(province)) {
            return null;
        }
        String result = province;
        if (StringUtils.isEmpty(city)) {
            return result;
        }
        result = result + "/" + city;
        if (StringUtils.isEmpty(country)) {
            return result;
        }
        result = result + "/" + country;
        if (StringUtils.isEmpty(store)) {
            return result;
        }
        return result + "/" + store;
    }

    private Integer status2Str(Integer status) {
        return status == null ? 0 : status;
    }

    /**
     * 设置价格
     *
     * @param list
     */
    private void setAvgPrice(List<SalesPlanEsEntity> list) {
        List<SkuPriceDTO> skuPriceDTOList = list.stream().filter(e -> avgPriceMap.get(e.getSku_key()) == null)
                .map(e -> {
                    SkuPriceDTO skuPriceDTO = new SkuPriceDTO();
                    skuPriceDTO.setSkuCode(e.getSku_key());
                    skuPriceDTO.setSaleUnitCode(e.getUnit());
                    return skuPriceDTO;
                })
                .collect(Collectors.toList());
        if (skuPriceDTOList.size() > 0) {
            Map<String, BigDecimal> skuAveragePrice = commonService.getSkuAveragePrice(skuPriceDTOList);
            avgPriceMap.putAll(skuAveragePrice);
        }
        list.forEach(dto -> {
            BigDecimal price = avgPriceMap.get(dto.getSku_key() + dto.getUnit());
            dto.setAveragePrice(price == null ? BigDecimal.ZERO : price);
        });
    }


    /**
     * 导出所有查询数据
     *
     * @param salesPlanOtherDTO
     * @param type
     * @throws Exception
     */
    @Override
    public ExcelExportDataDTO export(SalesPlanOtherDTO salesPlanOtherDTO, Integer type) throws Exception {
        // 获取日期标题
        List<String> dateTitles = MyDateUtil.processCyclesDate(salesPlanOtherDTO.getWeekDateList(), "MM.dd");
        //增加合计
        dateTitles.add("合计");
        List<SalesPlanOtherDTO> salesPlanDTOList = new ArrayList<>();
        List<List<Object>> exportDataList = null;
        Long userId = salesPlanOtherDTO.getCreator();
        //获取当前用户角色权限
        List<SalesPlanPermissionsDTO> roleAreaList = getRoleAreaList(userId);
        //一个用户只有一个级别（1:渠道、渠道下级（1级导入，确认），2：全渠道（2级确认））
        Integer level = roleAreaList.get(0).getPermissionsLevel();
        List<String> channels = new ArrayList<>();
        roleAreaList.forEach(item -> {
            String channel = item.getPermissionsCode();
            channels.add(channel);
        });
        //高级搜索不选择渠道，查询用户对应渠道
        if (CollectionUtils.isEmpty(salesPlanOtherDTO.getChannelCodeList())) {
            salesPlanOtherDTO.setChannelCodeList(channels);
        }
        //指标名称集合
        List<String> allTargetsDesc = SalesPlanOtherEnum.getAllTargetsDesc(level);
        List<SalesPlanOtherInfoDTO> salesPlan = new ArrayList<>();
        //全部数据导出
        if (ExcelExportTypeEnum.SEARCHED_DATA_EXPORT.getType().equals(type)) {
            List<Map<String, String>> mapList = salesPlanOtherRespository.listWeekBySelectiveAll(salesPlanOtherDTO);
            salesPlan = null;//groupTarget(mapList, level);
        }
        //当前页数据导出
        if (ExcelExportTypeEnum.CURRENT_PAGE_EXPORT.getType().equals(type)) {
            PageInfo<Map<String, String>> mapList = salesPlanOtherRespository.listWeekBySelective(salesPlanOtherDTO);
            salesPlan = null;//groupTarget(mapList.getList(), level);
        }
        //导出选中的数据
        if (ExcelExportTypeEnum.CHECKED_BOX_EXPORT.getType().equals(type)) {
            PageInfo<Map<String, String>> mapList = salesPlanOtherRespository.listWeekBySelective(salesPlanOtherDTO);
            salesPlan = null;//groupTarget(mapList.getList(), level);
        }
        if (CollectionUtils.isEmpty(salesPlan)) {
            throw new RomeException(ResponseMsg.FAIL_2005.getCode(), ResponseMsg.FAIL_2005.getMsg());
        }
        if (!SkuUnitTypeEnum.BASIS_UNIT.getUnitType().equals(salesPlanOtherDTO.getUnitType())) {
            List<String> skuCodeList = salesPlan.stream().map(SalesPlanOtherInfoDTO::getSkuCode).distinct().collect(Collectors.toList());
            //处理单位
            List<SkuUnitDTO> skuUnitList = itemCoreFacade.getConversionRatio(skuCodeList, salesPlanOtherDTO.getUnitType());
            this.calculationProBySelect(salesPlan, skuUnitList);
        }
        exportDataList = this.getExcelList(salesPlan, allTargetsDesc, dateTitles);
        List<List<String>> heads = new ArrayList<>();
        int mergeCellsColumns = this.setExcelTitles(heads, dateTitles);
        return ExcelExportUtil.getExcelExportData(mergeCellsColumns, exportDataList, heads, allTargetsDesc.size(), new GeneralCellWriteHandler());
    }

    private int setExcelTitles(List<List<String>> heads, List<String> dateTitles) {
        //获取高级搜索标题
        this.getExcelAdvancedSearchTitle(heads);
        int result = heads.size();
        //加入指标标题
        List<String> targetTitle = new ArrayList<>();
        targetTitle.add(ExcelExportTitleEnum.TARGET_TITLE.getTitle());
        heads.add(targetTitle);
        //加入日期标题
        AdvancedSearchUtil.getExcelDateTitle(heads, dateTitles);
        return result;
    }

    private void getExcelAdvancedSearchTitle(List<List<String>> heads) {
        setList(heads, ExcelExportTitleEnum.CHANNEL_TITLE.getTitle());
        setList(heads, ExcelExportTitleEnum.PLAN_TITLE.getTitle());
        setList(heads, ExcelExportTitleEnum.AREA_TITLE.getTitle());
        setList(heads, ExcelExportTitleEnum.STORE_TITLE.getTitle());
        setList(heads, ExcelExportTitleEnum.CATEGORY_TITLE.getTitle());
        setList(heads, ExcelExportTitleEnum.SKU_TITLE.getTitle());
    }


    private void getExcelAdvancedSearchTitle(List<List<String>> heads, String type) {
        setList(heads, ExportTemplateTitleEnum.CHANNEL_CODE_TITLE.getTitle());
        setList(heads, ExportTemplateTitleEnum.CHANNEL_NAME_TITLE.getTitle());
        setList(heads, ExportTemplateTitleEnum.PROVINCE_TITLE.getTitle());
        setList(heads, ExportTemplateTitleEnum.CITY_TITLE.getTitle());
        //新品、销售计划（直营、加盟有门店）
        if (SalesPlanTypeEnum.PLAN_ELEVEN.getType().equals(type) || SalesPlanTypeEnum.PLAN_SIXTEEN.getType().equals(type) || SalesPlanTypeEnum.PLAN_SEVENTEEN.getType().equals(type)) {
            setList(heads, ExportTemplateTitleEnum.STORE_TITLE.getTitle());
        }
        setList(heads, ExportTemplateTitleEnum.SKU_CODE_TITLE.getTitle());
        setList(heads, ExportTemplateTitleEnum.SKU_NAME_TITLE.getTitle());
        setList(heads, ExportTemplateTitleEnum.UNIT_TITLE.getTitle());
    }

    /**
     * 获取标题行list
     *
     * @param heads
     * @param title
     */
    private static void setList(List<List<String>> heads, String title) {
        List<String> list = new ArrayList<>();
        list.add(title);
        heads.add(list);
    }

    @Override
    public ExcelExportDataDTO downLoadTemplate(String type, String date) throws Exception {
        // 获取日期标题
        List<String> dateTitles = getTitleByDate(type, date);
        //获取上次导入的计划数据
        List<SalesWriteDTO> salesList = getLastWeekByType(type, date);
        //转换为导入模板的数据
        List<List<Object>> exportDataList = getExcelData(salesList, type);

        //获取excel标题 同时返回高级搜索标题的数量
        List<List<String>> heads = new ArrayList<>();
        setExcelTitle(heads, type, dateTitles);
        return ExcelExportUtil.getExcelExportData(exportDataList, heads, new GeneralCellWriteHandler());
    }

    private void setExcelTitle(List<List<String>> heads, String type, List<String> dateTitles) {
        //获取高级搜索标题
        this.getExcelAdvancedSearchTitle(heads, type);
        //加入日期标题
        AdvancedSearchUtil.getExcelDateTitle(heads, dateTitles);
    }

    /**
     * 获取当前日期对应的标题
     *
     * @return
     */
    private List<String> getTitleByDate(String type, String date) {
        List<String> result = new ArrayList<>();
        //List<Map<String, String>> dateMap = MyDateUtil.getWeekDateBySize(new Date(), CommonConstants.SIX);
        Date time = new Date();
        if (null != date) {
            time = DateUtil.parseDate(date);
        }
        List<Map<String, String>> dateMap = MyDateUtil.getWeekDateBySize(time, CommonConstants.SIX);
        //获取当前时间是多少周
        int dateIndex = DateUtil.weekOfYear(time);
        int i = 0;
        for (Map<String, String> map : dateMap) {
            String startDate = map.get("startTime");
            String endDate = map.get("endTime");
            if (i == 0) {
                result.add("当前周（销售数量）" + startDate + "-" + endDate);
            }
            if (SalesPlanTypeEnum.PLAN_FIFTEEN.getType().equals(type) || SalesPlanTypeEnum.PLAN_SIXTEEN.getType().equals(type)) {
                if (i == 1) {
                    result.add("W" + (dateIndex + i) + "（销售数量）（必填）" + startDate + "-" + endDate);
                }
                if (i == 2) {
                    result.add("W" + (dateIndex + i) + "（销售数量）（必填）" + startDate + "-" + endDate);
                }
                if (i == 3) {
                    result.add("W" + (dateIndex + i) + "（销售数量）（必填）" + startDate + "-" + endDate);
                }
                if (i == 4) {
                    result.add("W" + (dateIndex + i) + "（销售数量）（必填）" + startDate + "-" + endDate);
                }
            } else {
                if (i == 1) {
                    result.add("W" + (dateIndex + i) + "（销售数量）（必填）" + startDate + "-" + endDate);
                }
                if (i == 2) {
                    result.add("W" + (dateIndex + i) + "（销售数量）（必填）" + startDate + "-" + endDate);
                }
                if (i == 3) {
                    result.add("W" + (dateIndex + i) + "（销售数量）" + startDate + "-" + endDate);
                }
                if (i == 4) {
                    result.add("W" + (dateIndex + i) + "（销售数量）" + startDate + "-" + endDate);
                }

            }
            if (i == 5) {
                result.add("W" + (dateIndex + i) + "（销售数量）" + startDate + "-" + endDate);
            }
            if (i == 6) {
                result.add("W" + (dateIndex + i) + "（销售数量）" + startDate + "-" + endDate);
            }
            i++;
        }
        return result;
    }

    /**
     * 修改销售计划确认状态
     *
     * @return
     */
    @Override
    public void updateConfirmStatus() {
        asyncUpdateOtherEsStatus();
    }

    /**
     * 修改营销计划取消状态
     *
     * @return
     */
    @Override
    public void updateCancelStatus() {
        asyncUpdateOtherEsStatusYx();
    }

    /**
     * 更新数据中为空的仓库信息
     *
     * @return
     */
    @Override
    public void updateWarehouseCode() {
        updateOtherEsWarehouseCode();
    }
    
    @Override
    public void delete(String opSign) {
        salesPlanOtherRespository.delete(opSign);
    }

    private List<List<Object>> getExcelData(List<SalesWriteDTO> salesList, String type) {
        List<List<Object>> excelList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(salesList)) {
            for (SalesWriteDTO salesWriteDTO : salesList) {
                List<Object> item = new ArrayList<>();
                item.add(salesWriteDTO.getChannelCode());
                item.add(salesWriteDTO.getChannelName());
                item.add(salesWriteDTO.getProvinceName());
                item.add(ObjectUtil.isNotNull(salesWriteDTO.getCityName()) ? salesWriteDTO.getCityName() : "");
                if (SalesPlanTypeEnum.PLAN_ELEVEN.getType().equals(type) || SalesPlanTypeEnum.PLAN_SIXTEEN.getType().equals(type) || SalesPlanTypeEnum.PLAN_SEVENTEEN.getType().equals(type)) {
                    item.add(ObjectUtil.isNotNull(salesWriteDTO.getStoreCode()) ? salesWriteDTO.getStoreCode() : "");
                }
                item.add(salesWriteDTO.getSkuCode());
                item.add(salesWriteDTO.getSkuName());
                item.add(salesWriteDTO.getUnit());
                if (SalesPlanTypeEnum.PLAN_FIFTEEN.getType().equals(type)) {
                    item.add(salesWriteDTO.getWeekOneNum());
                    item.add(salesWriteDTO.getWeekTwoNum());
                    item.add(salesWriteDTO.getWeekThreeNum());
                    item.add(salesWriteDTO.getWeekFourNum());
                    item.add(salesWriteDTO.getWeekFiveNum());
                    item.add(salesWriteDTO.getWeekSixNum());
                    item.add(salesWriteDTO.getWeekSevenNum());
                } else {
                    item.add(salesWriteDTO.getWeekOneNum());
                    item.add("");
                    item.add("");
                    item.add("");
                    item.add("");
                    item.add("");
                    item.add("");
                }
                excelList.add(item);
            }
        }
        return excelList;
    }

    /**
     * 根据获取的换算比例计算指标数量(查询基础单位比例转换)
     */
    private List<SalesPlanOtherDTO> calculationProBySale(List<SalesPlanOtherDTO> resultList, List<SkuUnitDTO> skuUnitList) {
        if (CollectionUtils.isNotEmpty(skuUnitList) && CollectionUtils.isNotEmpty(resultList)) {
            skuUnitList.forEach(skuUnit -> {
                resultList.forEach(item -> {
                    if (item.getSkuCode().equals(skuUnit.getSkuCode())) {
                        item.setCouponQty(ObjectUtil.isNotEmpty(item.getCouponQty()) ? item.getCouponQty().multiply(BigDecimal.valueOf(skuUnit.getScale())) : BigDecimal.ZERO);
                        item.setPlanQty(ObjectUtil.isNotEmpty(item.getPlanQty()) ? item.getPlanQty().multiply(BigDecimal.valueOf(skuUnit.getScale())) : BigDecimal.ZERO);
                        item.setConfirmedQty(ObjectUtil.isNotEmpty(item.getConfirmedQty()) ? item.getConfirmedQty().multiply(BigDecimal.valueOf(skuUnit.getScale())) : BigDecimal.ZERO);
                        item.setChannelConfirmedQty(ObjectUtil.isNotEmpty(item.getChannelConfirmedQty()) ? item.getChannelConfirmedQty().multiply(BigDecimal.valueOf(skuUnit.getScale())) : BigDecimal.ZERO);
                        item.setAllchannelConfirmedQty(ObjectUtil.isNotEmpty(item.getAllchannelConfirmedQty()) ? item.getAllchannelConfirmedQty().multiply(BigDecimal.valueOf(skuUnit.getScale())) : BigDecimal.ZERO);
                    }
                });
            });
        }
        return resultList;
    }

    private List<List<Object>> getExcelList(List<SalesPlanOtherInfoDTO> salesPlan, List<String> targets, List<String> dateTitles) {
        List<SalesPlanOtherInfoDTO> salesPlanOtherInfoList = new ArrayList<>();
        List<List<Object>> exportDataList = new ArrayList<>();
        //将分组后的数据汇总
        salesPlan.forEach(key -> {
            for (int i = 0; i < targets.size(); i++) {
                List<Object> itemRow = new ArrayList<>();
                //加入渠道，区域，门店，品类，商品  信息
                itemRow.add(key.getChannel());
                itemRow.add(key.getType());
                itemRow.add(key.getArea());
                itemRow.add(ObjectUtil.isNotNull(key.getStore()) ? key.getStore() : "");
                itemRow.add(key.getCategory());
                itemRow.add(key.getSkuName());
                //加入指标
                itemRow.add(targets.get(i));
                //导入人没有下级确认量
                if (targets.size() == 6) {
                    //加入数据()
                    for (int j = 0; j < (dateTitles.size() - 1); j++) {
                        //获取指标集合，这里没有排序，默认使用枚举的顺序
                        switch (i) {
                            case 0:
                                itemRow.add(key.getLastPlanQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getLastPlanQtys().get(j));
                                break;
                            case 1:
                                itemRow.add(key.getLastConfirmedQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getLastConfirmedQtys().get(j));
                                break;
                            case 2:
                                itemRow.add(key.getPlanQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getPlanQtys().get(j));
                                break;
                            case 3:
                                itemRow.add(key.getConfirmedQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getConfirmedQtys().get(j));
                                break;
                            case 4:
                                itemRow.add(key.getPlanDifferences().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getPlanDifferences().get(j));
                                break;
                            case 5:
                                itemRow.add(key.getPlanProportions().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : (key.getPlanProportions().get(j).multiply(new BigDecimal(100)).setScale(3, BigDecimal.ROUND_HALF_UP)) + "%");
                                break;
                            default:
                                break;
                        }
                    }
                } else {
                    //加入数据
                    for (int j = 0; j < (dateTitles.size() - 1); j++) {
                        //获取指标集合，这里没有排序，默认使用枚举的顺序
                        switch (i) {
                            case 0:
                                itemRow.add(key.getLastPlanQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getLastPlanQtys().get(j));
                                break;
                            case 1:
                                itemRow.add(key.getLastConfirmedQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getLastConfirmedQtys().get(j));
                                break;
                            case 2:
                                itemRow.add(key.getPlanQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getPlanQtys().get(j));
                                break;
                            case 3:
                                itemRow.add(key.getSubordinateConfirmedQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getSubordinateConfirmedQtys().get(j));
                                break;
                            case 4:
                                itemRow.add(key.getConfirmedQtys().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getConfirmedQtys().get(j));
                                break;
                            case 5:
                                itemRow.add(key.getPlanDifferences().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : key.getPlanDifferences().get(j));
                                break;
                            case 6:
                                itemRow.add(key.getPlanProportions().get(j).compareTo(BigDecimal.ZERO) == 0 ? "-" : (key.getPlanProportions().get(j).multiply(new BigDecimal(100)).setScale(3, BigDecimal.ROUND_HALF_UP)) + "%");
                                break;
                            default:
                                break;
                        }
                    }
                }
                //合计
                BigDecimal total = BigDecimal.ZERO;
                String percentage = "";
                //获取除日期外的下标
                int index = itemRow.size() - (dateTitles.size() - 1);
                List<Object> numRow = new ArrayList<>();
                numRow.addAll(itemRow);
                for (int a = 0; a < index; a++) {
                    numRow.remove(numRow.get(0));
                }
                //循环增加查询的日期对应指标数量
                for (Object obj : numRow) {
                    BigDecimal num = BigDecimal.ZERO;
                    if ("-".equals(obj)) {
                        num = BigDecimal.ZERO;
                        total = total.add(num);
                    } else {
                        if (obj.toString().contains("%")) {
                            String nums = obj.toString().substring(0, obj.toString().length() - 1);
                            num = new BigDecimal(nums);
                            total = total.add(num);
                            percentage = total + "%";
                        } else {
                            num = new BigDecimal(obj.toString());
                            total = total.add(num);
                        }
                    }
                }
                if ("".equals(percentage)) {
                    itemRow.add(total.equals(BigDecimal.ZERO) ? "-" : total);
                } else {
                    itemRow.add(percentage);
                }
                exportDataList.add(itemRow);
            }
        });
        return exportDataList;
    }

    /**
     * 修改确认量
     *
     * @param ids
     * @param unitType
     * @param userId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirm(List<SalesPlanOtherDTO> otherList, Long unitType, Integer level) {
        //门店长度为4
        List<String> stoList = otherList.stream().filter(item -> ObjectUtil.isNull(item.getAreaCode()) || (ObjectUtil.isNotNull(item.getAreaCode()) && item.getAreaCode().length() == CommonConstants.FOUR)).map(SalesPlanOtherDTO::getArea).distinct().collect(Collectors.toList());
        List<String> provinceList = new ArrayList<>();
        //List<String> cityList = new ArrayList<>();
        List<String> storeList = new ArrayList<>();
        if (stoList.size() > 0) {
            //没有批量接口(门店数据量少)
            for (String code : stoList) {
                StoreDTO storeSimpleParamDTO = new StoreDTO();
                storeSimpleParamDTO.setCode(code.substring(code.length() - 4, code.length()));
                List<StoreDTO> storeLists = baseDataFacade.listStore(storeSimpleParamDTO).getList();
                if (storeLists.size() > 0) {
                    storeList.add(storeLists.get(0).getProvinceCode() + "/" + storeLists.get(0).getCityCode() + "/" + storeLists.get(0).getAreaCode() + "/" + storeLists.get(0).getCode());
                }
            }
        }
        //区域code
        List<String> list = otherList.stream().filter(item -> ObjectUtil.isNotNull(item.getAreaCode()) && item.getAreaCode().length() != 4).map(SalesPlanOtherDTO::getAreaCode).distinct().collect(Collectors.toList());
        /*List<AreaDTO> areaList = new ArrayList<>();
        if (list.size() > 0) {
            areaList = baseDataFacade.listAreaInfoByCode(list);
        }
        if (areaList.size() > 0) {
            //区域目前除了省就是市
            areaList.forEach(area -> {
                if (area.getLevel().equals(CommonConstants.ONE)) {
                    provinceList.add(area.getCode());
                } else {
                    cityList.add(area.getParentCode() + "/" + area.getCode());
                }
            });
        }*/
        provinceList.addAll(list);
        provinceList.addAll(storeList);
        List<String> typeList = new ArrayList<>();
        List<String> channelList = new ArrayList<>();
        otherList.forEach(item -> {
            typeList.add(item.getType());
            channelList.add(item.getChannelCode());
        });
        //获取所有的sku
        List<String> skuList = otherList.stream().map(SalesPlanOtherDTO::getSkuCode).distinct().collect(Collectors.toList());
        EsQueryDTO esQuery = new EsQueryDTO();
        esQuery.setChannelCodeList(channelList);
        esQuery.setTypeList(typeList);
        esQuery.setAreaCodeList(provinceList);
        List<Date> startDateList = otherList.stream().map(SalesPlanOtherDTO::getPlanStartDate).collect(Collectors.toList());
        esQuery.setStartDate(DateUtil.formatDate(Collections.min(startDateList)));
        List<Date> endDateList = otherList.stream().map(SalesPlanOtherDTO::getPlanEndDate).collect(Collectors.toList());
        esQuery.setEndDate(DateUtil.formatDate(Collections.max(endDateList)));
        List<SalesPlanSelectDTO> selectList = new ArrayList<>();
        for (String sku : skuList) {
            SalesPlanSelectDTO selectDto = new SalesPlanSelectDTO();
            selectDto.setCode(sku);
            selectDto.setLevel(CommonConstants.CATEGORY_LEVEL_FOUR);
            selectList.add(selectDto);
        }
        esQuery.setCategoryCodeList(selectList);
        //根据条件查询
        List<SalesPlanEsEntity> esList = salesPlanOtherEsRepository.listPageQuery(esQuery);
        //根据单位类型换算比例
        List<String> skuCodeList = esList.stream().map(SalesPlanEsEntity::getSku_key).distinct().collect(Collectors.toList());
        List<SkuUnitDTO> skuUnit = itemCoreFacade.getConversionRatio(skuCodeList, unitType);
        //转换成基本单位
        this.calculationBySaleConfirm(otherList, skuUnit, null);
        List<SalesPlanEsEntity> salesList = new ArrayList<>();
        try {
            //拆分确认量
            for (SalesPlanOtherDTO item : otherList) {
                //唯一
                List<SalesPlanEsEntity> entityList = esList.stream().filter
                        (es -> es.getChannel().equals(item.getChannelCode())
                                && (es.getProvince_code().equals(item.getAreaCode()) ||
                                (ObjectUtil.isNotNull(es.getCity_code()) ? es.getCity_code().equals(ObjectUtil.isNull(item.getAreaCode()) ? true : item.getAreaCode().substring(item.getAreaCode().length() - 6, item.getAreaCode().length())) : true) ||
                                (ObjectUtil.isNotNull(es.getNode_id()) ? es.getNode_id().equals(ObjectUtil.isNull(item.getAreaCode()) ? item.getArea().substring(item.getArea().length() - 4, item.getArea().length()) : item.getAreaCode().substring(item.getAreaCode().length() - 4, item.getAreaCode().length())) : true))
                                && es.getSku_key().equals(item.getSkuCode()) && es.getPlan_type().equals(item.getType())
                                && DateUtil.parseDate(es.getStart_date()).compareTo(item.getPlanStartDate()) == 0)
                        .collect(Collectors.toList());
                if (entityList.size() == 0) {
                    continue;
                }
                SalesPlanEsEntity entity = entityList.get(0);
                BigDecimal confirmQty = item.getConfirmedQty();
                if (level.equals(CommonConstants.OTHER_PLAN_LEVEL_TWO)) {
                    entity.setConfirm_l4(confirmQty);
                } else {
                    entity.setConfirm_l3(confirmQty);
                }
                salesList.add(entity);
            }
            //转换成页面选择的单位
            //this.calculationProBySaleConfirm(salesList, skuUnit, level);
            asyncUpdateOtherEsData1(salesList);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RomeException(ResponseMsg.FAIL.getCode(), ResponseMsg.FAIL.getMsg());
        }
        return Boolean.TRUE;
    }

    /**
     * 根据获取的换算比例计算指标数量(查询基础单位比例转换)(页面修改用)
     */
    private List<SalesPlanEsEntity> calculationProBySaleConfirm(List<SalesPlanEsEntity> resultList, List<SkuUnitDTO> skuUnitList, Integer level) {
        if (CollectionUtils.isNotEmpty(skuUnitList) && CollectionUtils.isNotEmpty(resultList)) {
            skuUnitList.forEach(skuUnit -> {
                resultList.forEach(item -> {
                    if (item.getSku_key().equals(skuUnit.getSkuCode())) {
                        if (level.equals(CommonConstants.OTHER_PLAN_LEVEL_TWO)) {
                            item.setConfirm_l4(ObjectUtil.isNotEmpty(item.getConfirm_l4()) ? item.getConfirm_l4().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        } else {
                            item.setConfirm_l3(ObjectUtil.isNotEmpty(item.getConfirm_l3()) ? item.getConfirm_l3().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        }
                    }
                });
            });
        }
        return resultList;
    }

    /**
     * 根据获取的换算比例计算指标数量(转换成页面选择的单位)(页面修改用)
     */
    private List<SalesPlanOtherDTO> calculationBySaleConfirm(List<SalesPlanOtherDTO> resultList, List<SkuUnitDTO> skuUnitList, Integer level) {
        if (CollectionUtils.isNotEmpty(skuUnitList) && CollectionUtils.isNotEmpty(resultList)) {
            skuUnitList.forEach(skuUnit -> {
                resultList.forEach(item -> {
                    if (item.getSkuCode().equals(skuUnit.getSkuCode())) {
                        item.setConfirmedQty(ObjectUtil.isNotEmpty(item.getConfirmedQty()) ? item.getConfirmedQty().multiply(BigDecimal.valueOf(skuUnit.getScale())) : BigDecimal.ZERO);
                    }
                });
            });
        }
        return resultList;
    }


    /**
     * 根据获取的换算比例计算指标数量(查询销售比例转换)
     */
    private List<SalesPlanEsEntity> calculationProEs(List<SalesPlanEsEntity> resultList, List<SkuUnitDTO> skuUnitList) {
        if (CollectionUtils.isNotEmpty(skuUnitList) && CollectionUtils.isNotEmpty(resultList)) {
            skuUnitList.forEach(skuUnit -> {
                resultList.forEach(item -> {
                    if (item.getSku_key().equals(skuUnit.getSkuCode())) {
                        //item.setCouponQty(ObjectUtil.isNotEmpty(item.getCouponQty()) ? item.getCouponQty().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        item.setPredict_sales(ObjectUtil.isNotEmpty(item.getPredict_sales()) ? item.getPredict_sales().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        item.setConfirm_l3(ObjectUtil.isNotEmpty(item.getConfirm_l3()) ? item.getConfirm_l3().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        item.setConfirm_l4(ObjectUtil.isNotEmpty(item.getConfirm_l4()) ? item.getConfirm_l4().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                    }
                });
            });
        }
        return resultList;
    }

    /**
     * 根据获取的换算比例计算指标数量(查询销售比例转换)
     */
    private List<SalesPlanOtherDTO> calculationPro(List<SalesPlanOtherDTO> resultList, List<SkuUnitDTO> skuUnitList) {
        if (CollectionUtils.isNotEmpty(skuUnitList) && CollectionUtils.isNotEmpty(resultList)) {
            skuUnitList.forEach(skuUnit -> {
                resultList.forEach(item -> {
                    if (item.getSkuCode().equals(skuUnit.getSkuCode())) {
                        item.setCouponQty(ObjectUtil.isNotEmpty(item.getCouponQty()) ? item.getCouponQty().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        item.setPlanQty(ObjectUtil.isNotEmpty(item.getPlanQty()) ? item.getPlanQty().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        item.setConfirmedQty(ObjectUtil.isNotEmpty(item.getConfirmedQty()) ? item.getConfirmedQty().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        item.setChannelConfirmedQty(ObjectUtil.isNotEmpty(item.getChannelConfirmedQty()) ? item.getChannelConfirmedQty().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                        item.setAllchannelConfirmedQty(ObjectUtil.isNotEmpty(item.getAllchannelConfirmedQty()) ? item.getAllchannelConfirmedQty().divide(BigDecimal.valueOf(skuUnit.getScale()), 7, BigDecimal.ROUND_HALF_UP) : BigDecimal.ZERO);
                    }
                });
            });
        }
        return resultList;
    }

    /**
     * 修改上次计划量，上次确认量
     */
    public void updateLastDate(List<SalesPlanOtherDTO> salesLists, Integer type) {
        //获取前一周到后五周的日期
        //List<Map<String, Date>> lastDateMap = MyDateUtil.getWeekDatess(new Date(), CommonConstants.SIX);
        List<Map<String, Date>> lastDateMap = MyDateUtil.getWeekDatess(salesLists.get(0).getPlanImportDate(), CommonConstants.SIX);
        //上一次计划第一周时间
        Date startTimeOne = lastDateMap.get(0).get("startTime");
        //上一次计划第二周时间（对应当前周）
        Date startTimeTwo = lastDateMap.get(1).get("startTime");
        //上一次计划第三周时间
        Date startTimeThree = lastDateMap.get(2).get("startTime");
        //上一次计划第四周时间
        Date startTimeFour = lastDateMap.get(3).get("startTime");
        //上一次计划第五周时间
        Date startTimeFive = lastDateMap.get(4).get("startTime");
        //上一次计划第六周时间
        Date startTimeSix = lastDateMap.get(5).get("startTime");
        //上一次计划第七周时间
        Date startTimeSeven = lastDateMap.get(6).get("startTime");
        List<String> plans = new ArrayList<>();
        String plana;
        String planb;
        String planc;
        String pland;
        String plane;
        //销售计划
        if (type == 1) {
            plana = SalesOtherTypeEnum.PLAN_ELEVEN.getType();
            planb = SalesOtherTypeEnum.PLAN_TWELVE.getType();
            planc = SalesOtherTypeEnum.PLAN_THIRTEEN.getType();
            pland = SalesOtherTypeEnum.PLAN_FOURTEEN.getType();
            plane = SalesOtherTypeEnum.PLAN_SIXTEEN.getType();
            plans.add(plana);
            plans.add(planb);
            plans.add(planc);
            plans.add(pland);
            plans.add(plane);
        }
        //新开店
        else if (type == 2) {
            plana = SalesOtherTypeEnum.PLAN_FIVE.getType();
            planb = SalesOtherTypeEnum.PLAN_SIX.getType();
            plans.add(plana);
            plans.add(planb);
        }
        //新品
        else if (type == 3) {
            plana = SalesOtherTypeEnum.PLAN_SEVEN.getType();
            planb = SalesOtherTypeEnum.PLAN_EIGHT.getType();
            planc = SalesOtherTypeEnum.PLAN_NINE.getType();
            pland = SalesOtherTypeEnum.PLAN_TEN.getType();
            plane = SalesOtherTypeEnum.PLAN_FIFTEEN.getType();
            plans.add(plana);
            plans.add(planb);
            plans.add(planc);
            plans.add(pland);
            plans.add(plane);
        }
        SalesPlanOtherDTO dto = new SalesPlanOtherDTO();
        //获取当前周第二周到第六周的数据
        EsQueryDTO esQuery = new EsQueryDTO();
        esQuery.setStartDate(DateUtil.formatDate(startTimeOne));
        esQuery.setImportDate(DateUtil.formatDate(startTimeTwo));
        esQuery.setEndDate(DateUtil.formatDate(startTimeSeven));
        esQuery.setTypeList(plans);
        List<SalesPlanEsEntity> esList = salesPlanOtherEsRepository.listPageQuery(esQuery);
        esList = esList.stream().filter(item -> DateUtil.parseDate(item.getStart_date()).compareTo(startTimeTwo) != 0).collect(Collectors.toList());
        if (esList.size() == 0) {
            return;
        }
        List<SalesPlanEsEntity> dtoList = new ArrayList<>();
        if (type == 1) {
            //销售计划
            esList.forEach(item -> {
                //筛选（计划类型、省份、城市、门店、商品、计划开始时间）
                List<SalesPlanOtherDTO> dtos = salesLists.stream().filter(dtoa ->
                        item.getChannel().equals(dtoa.getChannelCode()) &&
                                item.getPlan_type().equals(dtoa.getType()) &&
                                item.getProvince_code().equals(dtoa.getProvinceCode()) &&
                                (ObjectUtil.isNull(item.getCity_code()) ? true : (ObjectUtil.isNull(dtoa.getCityCode()) ? false : item.getCity_code().equals(dtoa.getCityCode()))) &&
                                (ObjectUtil.isNull(item.getNode_id()) ? true : (ObjectUtil.isNull(dtoa.getStoreCode()) ? false : item.getNode_id().equals(dtoa.getStoreCode()))) &&
                                item.getSku_key().equals(dtoa.getSkuCode()) &&
                                DateUtil.parseDate(item.getStart_date()).compareTo(dtoa.getPlanStartDate()) == 0)
                        .collect(Collectors.toList());
                //说明同一个省份下有多条记录
                if (dtos.size() > 1) {
                    //如果只有省
                    if (ObjectUtil.isNull(item.getCity_code()) && ObjectUtil.isNull(item.getNode_id())) {
                        //过滤去掉城市和门店为空的省份数据
                        dtos = dtos.stream().filter(repeat -> ObjectUtil.isNull(repeat.getCityCode())
                                && ObjectUtil.isNull(repeat.getStoreCode())).collect(Collectors.toList());
                    }
                    //如果有省和城市
                    else if (ObjectUtil.isNotNull(item.getCity_code()) && ObjectUtil.isNull(item.getNode_id())) {
                        //过滤去掉门店为空的数据
                        dtos = dtos.stream().filter(repeat -> ObjectUtil.isNull(repeat.getStoreCode())).collect(Collectors.toList());
                    }
                }
                if (dtos.size() == 1) {
                    item.setId(item.getId());
                    item.setBusiness_no(item.getBusiness_no());
                    item.setLast_predict_sales(item.getPredict_sales().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l3(item.getConfirm_l3().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l4(item.getConfirm_l4().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setConfirm_l4(BigDecimal.ZERO);
                    item.setConfirm_status_l4(SalesConfirmStatusEnum.UNCONFIRMED.getType());
                    //item.setImport_date(DateUtil.formatDate(new Date()));
                    item.setImport_date(DateUtil.formatDate(salesLists.get(0).getPlanImportDate()));
                    dtoList.add(item);
                } else {
                    item.setId(item.getId());
                    item.setBusiness_no(item.getBusiness_no());
                    item.setLast_predict_sales(item.getPredict_sales().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l3(item.getConfirm_l3().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l4(item.getConfirm_l4().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setPredict_sales(BigDecimal.ZERO);
                    item.setConfirm_l3(BigDecimal.ZERO);
                    item.setConfirm_l4(BigDecimal.ZERO);
                    item.setConfirm_status_l4(SalesConfirmStatusEnum.UNCONFIRMED.getType());
                    //item.setImport_date(DateUtil.formatDate(new Date()));
                    item.setImport_date(DateUtil.formatDate(salesLists.get(0).getPlanImportDate()));
                    dtoList.add(item);
                }
            });
        } else if (type == 2) {
            //新开店
            esList.forEach(item -> {
                //筛选（计划类型、省份、城市、门店、商品、计划开始时间）
                List<SalesPlanOtherDTO> dtos = salesLists.stream().filter(sale ->
                        sale.getType().equals(item.getPlan_type()) &&
                                sale.getSkuCode().equals(item.getSku_key()) &&
                                sale.getPlanStartDate().compareTo(DateUtil.parseDate(item.getStart_date())) == 0 &&
                                sale.getProvinceCode().equals(item.getProvince_code()) &&
                                (ObjectUtil.isNull(item.getCity_code()) ? true : (ObjectUtil.isNull(sale.getCityCode()) ? false : item.getCity_code().equals(sale.getCityCode())))).collect(Collectors.toList());
                //说明同一个省份下有多条记录
                if (dtos.size() > 1) {
                    //如果只有省
                    if (ObjectUtil.isNull(item.getCity_code())) {
                        //过滤去掉城市和门店为空的省份数据
                        dtos = dtos.stream().filter(repeat -> ObjectUtil.isNull(repeat.getCityCode())
                        ).collect(Collectors.toList());
                    }
                }
                if (dtos.size() == 1) {
                    item.setId(item.getId());
                    item.setBusiness_no(item.getBusiness_no());
                    item.setLast_predict_sales(item.getPredict_sales().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l3(item.getConfirm_l3().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l4(item.getConfirm_l4().setScale(0, BigDecimal.ROUND_HALF_UP));
                    //item.setImport_date(DateUtil.formatDate(new Date()));
                    item.setImport_date(DateUtil.formatDate(salesLists.get(0).getPlanImportDate()));
                    dtoList.add(item);
                } else {
                    item.setId(item.getId());
                    item.setBusiness_no(item.getBusiness_no());
                    item.setLast_predict_sales(item.getPredict_sales().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l3(item.getConfirm_l3().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l4(item.getConfirm_l4().setScale(0, BigDecimal.ROUND_HALF_UP));
                    //item.setImport_date(DateUtil.formatDate(new Date()));
                    item.setImport_date(DateUtil.formatDate(salesLists.get(0).getPlanImportDate()));
                    item.setPredict_sales(BigDecimal.ZERO);
                    item.setConfirm_l3(BigDecimal.ZERO);
                    item.setConfirm_l4(BigDecimal.ZERO);
                    dtoList.add(item);
                }
            });
        } else {
            //新品
            esList.forEach(item -> {
                //筛选（计划类型、省份、城市、门店、商品、计划开始时间）
                List<SalesPlanOtherDTO> dtos = salesLists.stream().filter(sale ->
                        sale.getType().equals(item.getPlan_type()) &&
                                sale.getSkuCode().equals(item.getSku_key()) &&
                                sale.getPlanStartDate().compareTo(DateUtil.parseDate(item.getStart_date())) == 0 &&
                                sale.getProvinceCode().equals(item.getProvince_code()) &&
                                (ObjectUtil.isNull(item.getCity_code()) ? true : (ObjectUtil.isNull(sale.getCityCode()) ? false : item.getCity_code().equals(sale.getCityCode()))) &&
                                (ObjectUtil.isNull(item.getNode_id()) ? true : (ObjectUtil.isNull(sale.getStoreCode()) ? false : item.getNode_id().equals(sale.getStoreCode())))).collect(Collectors.toList());
                //说明同一个省份下有多条记录
                if (dtos.size() > 1) {
                    //如果只有省
                    if (ObjectUtil.isNull(item.getCity_code()) && ObjectUtil.isNull(item.getNode_id())) {
                        //过滤去掉城市和门店为空的省份数据
                        dtos = dtos.stream().filter(repeat -> ObjectUtil.isNull(repeat.getCityCode())
                                && ObjectUtil.isNull(repeat.getStoreCode())).collect(Collectors.toList());
                    }
                    //如果有省和城市
                    else if (ObjectUtil.isNotNull(item.getCity_code()) && ObjectUtil.isNull(item.getNode_id())) {
                        //过滤去掉门店为空的数据
                        dtos = dtos.stream().filter(repeat -> ObjectUtil.isNull(repeat.getStoreCode())).collect(Collectors.toList());
                    }
                }
                if (dtos.size() == 1) {
                    item.setId(item.getId());
                    item.setBusiness_no(item.getBusiness_no());
                    item.setLast_predict_sales(item.getPredict_sales().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l3(item.getConfirm_l3().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l4(item.getConfirm_l4().setScale(0, BigDecimal.ROUND_HALF_UP));
                    //item.setImport_date(DateUtil.formatDate(new Date()));
                    item.setImport_date(DateUtil.formatDate(salesLists.get(0).getPlanImportDate()));
                    dtoList.add(item);
                } else {
                    item.setId(item.getId());
                    item.setBusiness_no(item.getBusiness_no());
                    item.setLast_predict_sales(item.getPredict_sales().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l3(item.getConfirm_l3().setScale(0, BigDecimal.ROUND_HALF_UP));
                    item.setLast_confirm_l4(item.getConfirm_l4().setScale(0, BigDecimal.ROUND_HALF_UP));
                    //item.setImport_date(DateUtil.formatDate(new Date()));
                    item.setImport_date(DateUtil.formatDate(salesLists.get(0).getPlanImportDate()));
                    item.setPredict_sales(BigDecimal.ZERO);
                    item.setConfirm_l3(BigDecimal.ZERO);
                    item.setConfirm_l4(BigDecimal.ZERO);
                    dtoList.add(item);
                }
            });
        }
        asyncUpdateOtherEsData1(dtoList);
    }

    private List<SalesWriteDTO> getLastWeekByType(String type, String date) {
        //List<Map<String, Date>> lastDateMap = MyDateUtil.getWeekDatess(new Date(), CommonConstants.SIX);
        Date time = new Date();
        if (null != date) {
            time = DateUtil.parseDate(date);
        }
        List<Map<String, Date>> lastDateMap = MyDateUtil.getWeekDatess(time, CommonConstants.SIX);
        //上一次计划第一周（当前）时间
        Date startTimeOne = lastDateMap.get(0).get("startTime");
        //上一次计划第二周时间（对应当前周）
        Date startTimeTwo = lastDateMap.get(1).get("startTime");
        //上一次计划第三周时间
        Date startTimeThree = lastDateMap.get(2).get("startTime");
        //上一次计划第四周时间
        Date startTimeFour = lastDateMap.get(3).get("startTime");
        //上一次计划第五周时间
        Date startTimeFive = lastDateMap.get(4).get("startTime");
        //上一次计划第六周时间
        Date startTimeSix = lastDateMap.get(5).get("startTime");
        //上一次计划第七周时间
        Date startTimeSeven = lastDateMap.get(6).get("startTime");
        List<String> types = new ArrayList<>();
        //新开店模板数据从品类接口获取
        if (SalesPlanTypeEnum.PLAN_FIFTEEN.getType().equals(type)) {
            List<StorePackageSkuDTO> skuDtoList = categoryFacade.queryStorePackageSku();
            if (CollectionUtils.isEmpty(skuDtoList)) {
                return Collections.emptyList();
            }
            List<SalesWriteDTO> writeDtoList = new ArrayList<>();
            for (StorePackageSkuDTO skuDto : skuDtoList) {
                SalesWriteDTO writeDto = new SalesWriteDTO();
                writeDto.setChannelCode(skuDto.getChannelCode());
                writeDto.setChannelName(skuDto.getChannelName());
                writeDto.setProvinceName(skuDto.getProvinceName());
                writeDto.setCityName(skuDto.getCityName());
                writeDto.setSkuCode(skuDto.getSkuCode());
                writeDto.setSkuName(skuDto.getSkuName());
                writeDto.setUnit(skuDto.getSaleUnitName());
                writeDto.setWeekOneNum(skuDto.getSkuQty().intValue());
                writeDto.setWeekTwoNum(skuDto.getSkuQty().intValue());
                writeDto.setWeekThreeNum(skuDto.getSkuQty().intValue());
                writeDto.setWeekFourNum(skuDto.getSkuQty().intValue());
                writeDto.setWeekFiveNum(skuDto.getSkuQty().intValue());
                writeDto.setWeekSixNum(skuDto.getSkuQty().intValue());
                writeDto.setWeekSevenNum(skuDto.getSkuQty().intValue());
                writeDtoList.add(writeDto);
            }
            return writeDtoList;
        } else if (SalesPlanTypeEnum.PLAN_SIXTEEN.getType().equals(type)) {
            types.add(SalesOtherTypeEnum.PLAN_SEVEN.getType());
            types.add(SalesOtherTypeEnum.PLAN_EIGHT.getType());
            types.add(SalesOtherTypeEnum.PLAN_NINE.getType());
            types.add(SalesOtherTypeEnum.PLAN_TEN.getType());
            types.add(SalesOtherTypeEnum.PLAN_FIFTEEN.getType());
        } else if (SalesPlanTypeEnum.PLAN_ELEVEN.getType().equals(type)) {
            types.add(SalesOtherTypeEnum.PLAN_ELEVEN.getType());
        } else if (SalesPlanTypeEnum.PLAN_TWELVE.getType().equals(type)) {
            types.add(SalesOtherTypeEnum.PLAN_TWELVE.getType());
        } else if (SalesPlanTypeEnum.PLAN_THIRTEEN.getType().equals(type)) {
            types.add(SalesOtherTypeEnum.PLAN_THIRTEEN.getType());
        } else if (SalesPlanTypeEnum.PLAN_FOURTEEN.getType().equals(type)) {
            types.add(SalesOtherTypeEnum.PLAN_FOURTEEN.getType());
        } else if (SalesPlanTypeEnum.PLAN_SEVENTEEN.getType().equals(type)) {
            types.add(SalesOtherTypeEnum.PLAN_SIXTEEN.getType());
        }
        EsQueryDTO esQuery = new EsQueryDTO();
        esQuery.setStartDate(DateUtil.formatDate(startTimeOne));
        esQuery.setImportDate(DateUtil.formatDate(startTimeTwo));
        esQuery.setEndDate(DateUtil.formatDate(startTimeSeven));
        esQuery.setTypeList(types);
        //查询ES对象集合
        List<SalesPlanEsEntity> dtoList = salesPlanOtherEsRepository.listPageQuery(esQuery);
        if (dtoList.size() == 0) {
            return Collections.emptyList();
        }
        //获取查询的集合不重复的省份CODE集合
        List<String> proCodeList = dtoList.stream().map(SalesPlanEsEntity::getProvince_code).distinct().collect(Collectors.toList());
        List<AreaDTO> provinceList = baseDataFacade.listAreaInfoByCode(proCodeList);
        //获取查询的集合不重复的城市CODE集合
        List<String> cityCodeList = dtoList.stream().map(SalesPlanEsEntity::getCity_code).distinct().collect(Collectors.toList());
        List<AreaDTO> cityList = baseDataFacade.listAreaInfoByCode(cityCodeList);
        //获取所有不重复的商品编码
        List<String> skus = dtoList.stream().map(SalesPlanEsEntity::getSku_key).distinct().collect(Collectors.toList());
        //获取单位转换比例信息
        List<SkuUnitDTO> unitList = itemCoreFacade.getConversionRatio(skus, SkuUnitTypeEnum.SALES_UNIT.getUnitType());
        //转换为销售单位
        this.calculationProEs(dtoList, unitList);
        //根据类型、省份、城市、门店（没有为""）、商品分组
        Map<String, List<SalesPlanEsEntity>> dateMap = dtoList.stream().collect(Collectors.groupingBy
                (item -> item.getPlan_type() + item.getProvince_code()
                        + (ObjectUtil.isNotNull(item.getCity_code()) ? item.getCity_code() : "")
                        + (ObjectUtil.isNotNull(item.getNode_id()) ? item.getNode_id() : "") + item.getSku_key()));
        List<SalesWriteDTO> writeList = new ArrayList<>();
        dateMap.forEach((k, v) -> {
            SalesWriteDTO writeDto = new SalesWriteDTO();
            writeDto.setPlanNo(v.get(0).getBusiness_no());
            writeDto.setChannelCode(v.get(0).getChannel());
            writeDto.setChannelName(ChannelTypeEnum.getNameByCode(v.get(0).getChannel()));
            writeDto.setStoreCode(v.get(0).getNode_id());
            writeDto.setSkuCode(v.get(0).getSku_key());
            List<AreaDTO> provinces = provinceList.stream().filter(pro -> pro.getCode().equals(v.get(0).getProvince_code())).collect(Collectors.toList());
            if (provinces.size() > 0) {
                writeDto.setProvinceName(provinces.get(0).getName());
            }
            List<AreaDTO> citys = cityList.stream().filter(city -> city.getCode().equals(v.get(0).getCity_code())).collect(Collectors.toList());
            if (citys.size() > 0) {
                writeDto.setCityName(citys.get(0).getName());
            }
            //需要转换
            List<SkuUnitDTO> skuUnits = unitList.stream().filter(unit -> unit.getSkuCode().equals(v.get(0).getSku_key())).collect(Collectors.toList());
            if (skuUnits.size() > 0) {
                writeDto.setUnit(skuUnits.get(0).getUnitName());
                writeDto.setSkuName(skuUnits.get(0).getSkuName());
            }
            v.forEach(dto -> {
                Date startDate = DateUtil.parseDate(dto.getStart_date());
                if (startTimeTwo.compareTo(startDate) == 0) {
                    writeDto.setWeekOneNum(dto.getPredict_sales().intValue());
                } else if (startTimeThree.compareTo(startDate) == 0) {
                    writeDto.setWeekTwoNum(dto.getPredict_sales().intValue());
                } else if (startTimeFour.compareTo(startDate) == 0) {
                    writeDto.setWeekThreeNum(dto.getPredict_sales().intValue());
                } else if (startTimeFive.compareTo(startDate) == 0) {
                    writeDto.setWeekFourNum(dto.getPredict_sales().intValue());
                } else if (startTimeSix.compareTo(startDate) == 0) {
                    writeDto.setWeekFiveNum(dto.getPredict_sales().intValue());
                } else if (startTimeSeven.compareTo(startDate) == 0) {
                    writeDto.setWeekSixNum(dto.getPredict_sales().intValue());
                }
            });
            writeList.add(writeDto);
        });
        return writeList;
    }

    private List<SalesPlanOtherDTO> getSaleList(List<SalesPlanOtherSimpleDTO> simpleList, List<SkuInfosDTO> skus, List<CategorySimpleDTO> categorys, List<AreaDTO> provinceList,
                                                List<AreaDTO> cityNameList,
                                                List<StoreDTO> storeList, List<AreaDTO> provinceListByStore, List<AreaDTO> cityListByStore,
                                                List<AreaDTO> countyListByStore, List<AreaDTO> provinceNameListByCity,
                                                List<SkuUnitExtDTO> skuUnitList) {

        List<SalesPlanOtherDTO> dtoList = new ArrayList<>();
        for (SalesPlanOtherSimpleDTO simpleDto : simpleList) {
            for (OtherSimpleDTO otherDto : simpleDto.getList()) {
                SalesPlanOtherDTO dto = new SalesPlanOtherDTO();
                dto.setPlanImportDate(ObjectUtil.isNotNull(simpleDto.getImportDate()) ? DateUtil.parseDate(simpleDto.getImportDate()) : new Date());
                dto.setSalesPlanActivityNo(simpleDto.getSalesPlanActivityNo());
                dto.setStatus(SalesConfirmStatusEnum.CONFIRMED.getType());
                dto.setSkuTypeCode(simpleDto.getSkuTypeCode());
                dto.setChannelConfirmedQty(otherDto.getConfirmedQty());
                dto.setAllchannelConfirmedQty(otherDto.getConfirmedQty());
                dto.setPlanStartDate(DateUtil.parseDate(otherDto.getPlanWeek().split("-")[0]));
                dto.setPlanEndDate(DateUtil.parseDate(otherDto.getPlanWeek().split("-")[1]));
                dto.setCreator(1L);
                dto.setCreatorName("营销中心导入");
                dto.setModifier(1L);
                dto.setModifierName("营销中心导入");
                String type;
                String channelName;
                if (ChannelTypeEnum.DIRECTLY_OPERATE.getCode().equals(simpleDto.getChannelCode())) {
                    type = SalesOtherTypeEnum.PLAN_ONE.getType();
                    channelName = ChannelTypeEnum.DIRECTLY_OPERATE.getDesc();
                } else if (ChannelTypeEnum.JOIN_IN.getCode().equals(simpleDto.getChannelCode())) {
                    type = SalesOtherTypeEnum.PLAN_TWO.getType();
                    channelName = ChannelTypeEnum.JOIN_IN.getDesc();
                } else if (ChannelTypeEnum.CLOUD_BUSINESS.getCode().equals(simpleDto.getChannelCode())) {
                    type = SalesOtherTypeEnum.PLAN_THREE.getType();
                    channelName = ChannelTypeEnum.CLOUD_BUSINESS.getDesc();
                } else {
                    type = SalesOtherTypeEnum.PLAN_FOUR.getType();
                    channelName = ChannelTypeEnum.APP.getDesc();
                }
                dto.setType(type);
                dto.setChannelCode(simpleDto.getChannelCode());
                dto.setChannelName(channelName);
                if (ObjectUtil.isNotNull(simpleDto.getStoreCode())) {
                    List<StoreDTO> stores = storeList.stream().filter(store -> store.getCode().equals(simpleDto.getStoreCode())).collect(Collectors.toList());
                    String provinceCode = stores.get(0).getProvinceCode();
                    String cityCode = stores.get(0).getCityCode();
                    String countCode = stores.get(0).getAreaCode();
                    //匹配对应的省市区
                    List<AreaDTO> proList = provinceListByStore.stream().filter(pro -> pro.getCode().equals(provinceCode)).collect(Collectors.toList());
                    List<AreaDTO> cityList = cityListByStore.stream().filter(pro -> pro.getCode().equals(cityCode)).collect(Collectors.toList());
                    List<AreaDTO> countList = countyListByStore.stream().filter(pro -> pro.getCode().equals(countCode)).collect(Collectors.toList());
                    if (proList.size() > 0) {
                        dto.setProvinceCode(proList.get(0).getCode());
                        dto.setProvinceName(proList.get(0).getName());
                    }
                    if (cityList.size() > 0) {
                        dto.setCityCode(cityList.get(0).getCode());
                        dto.setCityName(cityList.get(0).getName());
                    }
                    if (countList.size() > 0) {
                        dto.setCountyCode(countList.get(0).getCode());
                        dto.setCountyName(countList.get(0).getName());
                    }
                }
                //如果填了城市
                List<AreaDTO> city = cityNameList.stream().filter(pro -> ObjectUtil.isNotNull(simpleDto.getCityName()) && pro.getName().contains(simpleDto.getCityName())).collect(Collectors.toList());
                if (city.size() > 0) {
                    if (provinceNameListByCity.size() > 0) {
                        List<AreaDTO> province = provinceNameListByCity.stream().filter(pro -> pro.getName().contains(simpleDto.getProvinceName())).collect(Collectors.toList());
                        if (province.size() > 0) {
                            dto.setProvinceCode(province.get(0).getCode());
                            dto.setProvinceName(province.get(0).getName());
                        }
                    }
                    dto.setCityCode(city.get(0).getCode());
                    dto.setCityName(city.get(0).getName());
                } else {
                    //省份必填(填了城市取城市)
                    List<AreaDTO> province = provinceList.stream().filter(pro -> pro.getName().contains(simpleDto.getProvinceName())).collect(Collectors.toList());
                    if (province.size() > 0) {
                        dto.setProvinceCode(province.get(0).getCode());
                        dto.setProvinceName(province.get(0).getName());
                    }
                }
                //获取商品信息
                List<SkuInfosDTO> skuInfo = skus.stream().filter(sku -> sku.getSkuCode().equals(simpleDto.getSkuCode())).collect(Collectors.toList());
                if (skuInfo.size() > 0) {
                    List<CategorySimpleDTO> category = categorys.stream().filter(ter -> ter.getId().equals(skuInfo.get(0).getCategoryId())).collect(Collectors.toList());
                    if (category.size() > 0) {
                        category.get(0).getParentCategoryDTOList().forEach(cate -> {
                            if (cate.getCategoryLevel().equals(CommonConstants.CATEGORY_LEVEL_ONE)) {
                                dto.setPriCategoryCode(cate.getCategoryCode().toString());
                                dto.setPriCategoryName(cate.getCategoryName());
                            } else if (cate.getCategoryLevel().equals(CommonConstants.CATEGORY_LEVEL_TWO)) {
                                dto.setSecCategoryCode(cate.getCategoryCode().toString());
                                dto.setSecCategoryName(cate.getCategoryName());
                            } else if (cate.getCategoryLevel().equals(CommonConstants.CATEGORY_LEVEL_THREE)) {
                                dto.setTerCategoryCode(cate.getCategoryCode().toString());
                                dto.setTerCategoryName(cate.getCategoryName());
                            }
                        });
                    }
                    List<SkuUnitExtDTO> units = skuUnitList.stream().filter(ter -> ter.getSkuCode().equals(skuInfo.get(0).getSkuCode())).collect(Collectors.toList());
                    if (units.size() > 0) {
                        dto.setUnitCode(units.get(0).getUnitCode());
                        dto.setUnitName(units.get(0).getUnitName());
                    }
                    dto.setSkuCode(skuInfo.get(0).getSkuCode());
                    dto.setSkuName(skuInfo.get(0).getSkuName());
                }
                dtoList.add(dto);
            }

        }
        return dtoList;
    }
}
